javascriptecmascript-6ecmascript-harmony

[[Class]] property in JavaScript objects


The [[Class]] property of object is set according to how an object is created IIUC.

Is this why some objects are rendered to the Chrome console in a meaningful way e.g. MyFoo and others are simply rendered as Object?

With the new object literal syntax in ES6 for configuring the prototype chain. Can I modify the [[Class]] property of the resulting object, so that it is rendered in a more meaningful way to the console?

var x = { __proto__: MyCtor.prototype };
console.log(x); // I want something like MyCtor to be logged to the console

I note that in Safari 8 on a Mac the above renders MyCtor to the console. Chrome on the Mac does not.

PS: perhaps this is due to my confusing of browsers that support this prototype chain initialization syntax.


Solution

  • Can I modify the [[Class]] property of the resulting object

    Well, there is a trick here. The internal property [[Class]] has been removed in ES-6. But, the only way to get the value from [[Class]] was the Object.prototype.toString.call method. Now, you can customize that to return whatever name you want. Quoting the draft version of ECMA Script 6,

    1. Let tag be Get (O, @@toStringTag).
    2. ReturnIfAbrupt(tag).
    3. If Type(tag) is not String, let tag be builtinTag.
    4. Return the String that is the result of concatenating "[object ", tag, and "]".

    So, if we can change the @@toStringTag, we can actually change result of Object.prototype.toString.call. We change it like this

    var obj = {};
    
    Object.defineProperty(obj, Symbol.toStringTag, {
        get: function() {
            return "MyClass";
        }
    });
    
    console.log(Object.prototype.toString.call(obj));
    # [object MyClass]
    

    Note: The above seen program is tested in iojs (v1.0.2 with --harmony flags enabled).