2

首先,这是一个按预期工作的示例:

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具有该属性的原型被分配给它?

4

1 回答 1

1

__proto__是一个 getter 和 setter on Object.prototype

> Object.getOwnPropertyDescriptor(Object.prototype, '__proto__')
{ get: [Function: get __proto__],
  set: [Function: set __proto__],
  enumerable: false,
  configurable: true }

如果您创建一个不继承自 的对象,则Object.prototype它没有该特殊属性,并且设置__proto__将像其他任何属性一样创建一个完全正常的属性。

这是Object.prototype.__proto__设置原型而不是创建属性的设置器:

> var a = {};
> a.__proto__ = { foo: 'bar' };
> Object.prototype.hasOwnProperty.call(a, '__proto__')
false

这是因为Object.prototype不在链中而未使用的设置器:

> var b = Object.create(null);
> b.__proto__ = { foo: 'bar' };
> Object.prototype.hasOwnProperty.call(b, '__proto__')
true

改用Object.setPrototypeOf(总是):

Object.setPrototypeOf(a, b);
于 2017-05-31T03:28:44.420 回答