我观察到一个关于 __proto__
的行为,这对我来说似乎很奇怪:当将 __proto__
更改为各种对象时,它的行为符合预期,但一旦它被设置为 null
再次将其更改为另一个对象似乎没有效果。
这是实现中的错误,还是预期的行为?如果这是所需的行为,有人可以阐明原因吗?
一个示例 JavaScript 代码(所有测试都顺利通过,直到最后一行):
p = {
sum: function() {
return this.x + this.y;
}
};
o = {
x: 1,
y: 2
};
o.sum(); // As expected: TypeError: o.sum is not a function
// These all behave as expected:
o.__proto__ = p;
o.__proto__; // [object Object]
o.__proto__.sum; // [object Function]
o.sum(); // returns 3 :-)
// These all behave as expected:
o.__proto__ = {};
o.__proto__; // [object Object]
o.sum(); // TypeError: o.sum is not a function
// These all behave as expected:
o.__proto__ = p;
o.__proto__; // [object Object]
o.__proto__.sum; // [object Function]
o.sum(); // returns 3 :-)
// Still behaves more or less as expected:
o.__proto__ = null;
o.__proto__; // undefined (why undefined and not null?)
o.sum(); // TypeError: o.sum is not a function
// Seems fine, until the last line:
o.__proto__ = p;
o.__proto__; // [object Object]
o.__proto__.sum; // [object Function]
o.sum(); // Expected 3, but... TypeError: o.sum is not a function
我正在使用 Firefox 28.0;不知道其他浏览器如何 react 。
最佳答案
问题是 __proto__
在 Firefox 中是 Object.prototype
上的实际属性(property)用 getter/setter
实现功能。所以当你设置 __proto__
的 o
至 null
,你消灭了整个原型(prototype)链,其中包括 __proto__
属性(property)。
现在,当您分配给 __proto__
时,您只是将没有所需行为的新的普通属性直接分配给 o
对象。
所以为了得到__proto__
的功能,您需要转到 Object.prototype
, 并借用 .set
__proto__
的方法属性(property),并使用.call
允许它在 o
上运行对象。
Object.getOwnPropertyDescriptor(Object.prototype, "__proto__").set.call(o, p);
所以这会调用 set
Object.prototype.__proto__
的功能使用 .call
这样 o
变成 this
set
的值, 和 p
是正在设置的值。这将使 __proto__
在 o
上操作就好像它是 o
的属性一样, 允许它设置内部 [[Prototype]]
属性(property)。
请注意,这仅在 Firefox 中进行了测试。
关于javascript - __proto__ 在空赋值后似乎不起作用 - 错误或功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23521314/