【发布时间】:2016-12-25 10:15:46
【问题描述】:
考虑以下两个sn-ps:
obj = {}; // can be [], Number(), eg. but not Function()
obj[Symbol.hasInstance] = () => console.log('89');
({}) instanceof obj;
和
obj = function() {}; // new Function() too
obj[Symbol.hasInstance] = () => console.log('89');
({}) instanceof obj;
两者都应该记录“89”,但仅在第一个 sn-p 中记录“89”。
在 Chrome 52 中,第一个记录 89,第二个不记录任何内容。
在节点 v6.3.1 中,第一个结果是 TypeError: Expecting a function in instanceof check, but got #<Object>,而第二个没有记录。
这是一个错误吗?预期的行为是什么?在 MDN 上没有任何解释。
【问题讨论】:
-
规范说 “这个属性是不可写和不可配置的,以防止可用于全局暴露绑定函数的目标函数的篡改。” 但它还说 “构造函数可以通过在函数上公开不同的 @@hasInstance 方法来控制
instanceof将哪些对象识别为其实例。” ecma-international.org/ecma-262/7.0/… 。根据ecma-international.org/ecma-262/7.0/#sec-instanceofoperator,第一个不应该在 Node.js 中抛出错误。看来 Chrome 是正确的。 -
但是,
@@hasInstance在原型链中,我实际上并没有改变它,只是在obj上创建另一个属性@@hasInstance。new Function()和function() {}也是如此,为什么他们的行为不同? -
如果一个属性是不可写的,你不能分配给它在链中更高的位置。示例:
var a = Object.create(null, {test: {value: 42}}); var b = Object.create(a);。b.test = 21;静默失败。
标签: javascript google-chrome reflection ecmascript-6 symbols