javascript - __proto__ 在空赋值后似乎不起作用 - 错误或功能?

标签 javascript

我观察到一个关于 __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__onull ,你消灭了整个原型(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/

相关文章:

javascript - Datepicker 弹出第一个焦点

javascript - 在 Firefox 中使用 JavaScript href 为谷歌翻译刷新页面

javascript - 如何获取相应按钮的值属性?

javascript - Jquery 在父级之外查找 ID 或表单

Javascript:需要注册表单帮助

javascript - jQuery 显示打开的同级,同时关闭先前打开的同级

javascript - 用 Flot 识别悬停点?

javascript - 如何在 ng-options 中设置默认值

Javascript:标准化函数中的参数,我应该复制它吗?

javascript - JavaScript Chrome 控制台中的脚本未打印错误