__proto__似乎在null赋值后不起作用 - bug或功能? [英] __proto__ doesn't seem to work after a null assignment - bug or feature?

查看:231
本文介绍了__proto__似乎在null赋值后不起作用 - bug或功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我观察到有关 __ 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 ,允许它设置内部 [[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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆