__proto__似乎在null赋值后不起作用 - bug或功能? [英] __proto__ doesn't seem to work after a null assignment - bug or feature?
问题描述
我观察到有关 __ proto __
的行为,这对我来说很奇怪:将 __ proto __
更改为其行为的各种对象时正如所料,但一旦设置为 null
再次将其更改为另一个对象似乎没有效果。
I have observed a behaviour regarding __proto__
which seems weird to me: when changing __proto__
to various objects it behaves as expected, but once it is set to null
changing it again to another object doesn't seem to have an effect.
这是实施中的错误还是所需的行为?如果这是期望的行为,有人可以解释为什么吗?
Is this a bug in the implementation, or the desired behaviour? If this is the desired behaviour, can someone shed a light as to why?
一个示例JavaScript代码(所有测试都通过直到最后一行):
An example JavaScript code (all the tests pass fine until the last line):
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;不知道其他浏览器的反应。
I'm working with Firefox 28.0; don't know how other browsers react.
推荐答案
问题是 __ proto __
在Firefox中是使用 getter / setter
函数实现的 Object.prototype
的实际属性。因此,当您将 __ proto __
o
设置为 null
时,你消灭了整个原型链,其中包括 __ proto __
属性。
The issue is that __proto__
in Firefox is an actual property on Object.prototype
implemented with getter/setter
functions. So when you set the __proto__
of o
to null
, you wiped out the entire prototype chain, which included the __proto__
property.
现在分配给 __ proto __
,您只是将一个新的,普通的属性直接分配给 o
对象。
Now when you assign to __proto__
, you're just assigning a new, normal property that doesn't have the desired behavior directly to the o
object.
因此,为了获得 __ proto __
的功能,你'我需要转到 Object.prototype
,并借用 __ proto__的
属性,并使用 .set
方法 .call
允许它在 o
对象上运行。
So in order to get the functionality of __proto__
, you'll need to go to Object.prototype
, and borrow the .set
method of the __proto__
property, and use .call
to allow it to operate on the o
object.
Object.getOwnPropertyDescriptor(Object.prototype, "__proto__").set.call(o, p);
所以这会调用 set
的函数 Object.prototype .__ proto __
使用 .call
以便 o
成为此
值设置
, p
是价值被设定。这将使 __ proto __
对 o
进行操作,就像它是 o $的属性一样c $ c>,允许它设置内部
[[Prototype]]
属性。
So this invokes the set
function of Object.prototype.__proto__
using .call
so that the o
becomes the this
value of set
, and p
is the value being set. This will make __proto__
operate on o
as though it was a property of o
, allowing it to set the internal [[Prototype]]
property.
请注意,这仅在Firefox中测试。
Note that this is only tested in Firefox.
这篇关于__proto__似乎在null赋值后不起作用 - bug或功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!