对象的
[[Class]]
属性是根据对象的创建方式设置的 IIUC。
这就是为什么某些对象以有意义的方式呈现到 Chrome 控制台的原因,例如
MyFoo
和其他简单地呈现为 Object
?
使用 ES6 中新的对象字面量语法来配置原型链。我可以修改结果对象的
[[Class]]
属性,以便以更有意义的方式呈现到控制台吗?
var x = { __proto__: MyCtor.prototype };
console.log(x); // I want something like MyCtor to be logged to the console
我注意到,在 Mac 上的 Safari 8 中,上面的内容会将
MyCtor
渲染到控制台。 Mac 上的 Chrome 没有。
PS:也许这是因为我对支持这种原型链初始化语法的浏览器感到困惑。
我可以修改生成对象的
属性吗[[Class]]
嗯,这里有一个技巧。内部属性
[[Class]]
已在 ES-6 中删除。但是,从 [[Class]]
获取值的唯一方法是 Object.prototype.toString.call
方法。现在,您可以自定义它以返回您想要的任何名称。引用 ECMA Script 6 的草案版本,
- 令标签为
。Get (O, @@toStringTag)
.ReturnIfAbrupt(tag)
- 如果
不是Type(tag)
,则令String
为tag
。builtinTag
- 返回连接
后的字符串。"[object ", tag, and "]"
所以,如果我们可以改变
@@toStringTag
,我们实际上可以改变Object.prototype.toString.call
的结果。我们这样改
var obj = {};
Object.defineProperty(obj, Symbol.toStringTag, {
get: function() {
return "MyClass";
}
});
console.log(Object.prototype.toString.call(obj));
# [object MyClass]
注意: 上面看到的程序是在 iojs 中测试的(v1.0.2,启用了 --harmony 标志)。
ES6 中没有 [[Class]],有 内在对象。
如果您使用 Object.prototype.toString.call(x),其中 x 是任何内置类实例,那么它会给您类似 [object Array]、[object Function] 的结果,因为 x 是数组的实例但如果 x 是用户定义类的对象,那么这将简单地返回 [object Object]。为了克服这个问题,我们可以在用户定义的类中定义一个 [Symbol.toStringTag] 方法,该方法返回一个字符串来描述对象类型,当我们使用 Object.prototype.toString() 时,它首先在争论。
class CustomClass {
constructor() {}
}
CustomClass.prototype[Symbol.toStringTag] = 'CustomClass';
const obj = new CustomClass();
console.log(Object.prototype.toString.call(obj));
这将导致输出 [[object CustomClass]]。 但您可能想知道,由于 Object.prototype.toString.call() 适用于内置类型,因此像 Array、Function 这样的类可能已经拥有此 Object.prototype.toString 正在使用的 [Symbol.toStringTag],但是如果你登录Array.prototype,没有定义这样的方法。 所以对于内置类型,Object.prototype.toString()实际上是寻找一个内部属性[[class]]来确定对象的类型。