首先,这是一个按预期工作的示例:
let a = { foo: 10 }
let b = { bar: 20 }
a.__proto__ = b
// returns value from prototype just fine
a.bar; // 20
这是一个问题的例子,它没有按预期工作。为什么呢?
// "a" has no prototype when created this way
let a = Object.create(null);
// "b" has prototype and it is a JS native Object with a whole slew of its native props
let b = {};
// assign "a" a prototype
a.__proto__ = b;
// let's try
a.toString; // undefined
// but...
a.__proto__ .toString; // function toString() { [native code] }
为什么a.toString
会返回undefined
,尽管已为其分配了具有该属性的原型?
答案 0 :(得分:1)
__proto__
是Object.prototype
上的getter和setter。
> Object.getOwnPropertyDescriptor(Object.prototype, '__proto__')
{ get: [Function: get __proto__],
set: [Function: set __proto__],
enumerable: false,
configurable: true }
如果您创建的对象不是从Object.prototype
继承的,则它没有该特殊属性,设置__proto__
将创建一个完全正常的属性,就像其他任何属性一样。
这是Object.prototype.__proto__
的setter设置原型而不是创建属性:
> var a = {};
> a.__proto__ = { foo: 'bar' };
> Object.prototype.hasOwnProperty.call(a, '__proto__')
false
并且这里没有使用setter,因为Object.prototype
不在链中:
> var b = Object.create(null);
> b.__proto__ = { foo: 'bar' };
> Object.prototype.hasOwnProperty.call(b, '__proto__')
true
使用Object.setPrototypeOf
代替(总是):
Object.setPrototypeOf(a, b);