Почему obj.constructor.prototype не всегда равен obj .__ proto__? - PullRequest
7 голосов
/ 01 августа 2020
function Product(name, price) {
  this.name = name;
  this.price = price;
}

const p1 = new Product('Pen', 20);
const p2 = Object.create(p1);

console.log(p1.constructor.prototype === p1.__proto__);  // true
console.log(p2.constructor.prototype === p2.__proto__);  // false

Насколько я понимаю, эти два всегда равны (как в первом операторе console.log).

Но, делая некоторые настройки, я обнаружил этот удивительный результат (второй оператор console.log).

Кто-нибудь, пожалуйста, проясните мое понимание взаимосвязи между prototype и __proto__. Заранее спасибо!

1 Ответ

8 голосов
/ 01 августа 2020

Это работает только для экземпляров, созданных с использованием new из конструкторов, которые следуют стандартному шаблону прототипа. Эти объекты будут унаследованы от конструктора объекта .prototype, у которого есть свойство .constructor, указывающее обратно на конструктор. Это означает, что при доступе к унаследованному .constructor мы можем найти объект-прототип, который мы наследуем от него.

Однако это не работает для произвольных объектов, имеющих собственное свойство .constructor (например, {constructor: null}) или для объектов, которые не наследуются напрямую от объекта-прототипа конструктора, например вашего p2.

Чтобы прояснить, что происходит в вашем коде без использования new:

const Product = Object.create(Function.prototype);
Product.prototype = Object.create(Object.prototype);
Product.prototype.constructor = Product;

const p1 = Object.create(Product.prototype);
p1.name = "Pen";
p1.price = 20;
console.assert(Product.prototype == Object.getPrototypeOf(p1));
console.assert(!p1.hasOwnProperty("constructor") && p1.constructor == Product);
console.assert(p1.constructor.prototype == Product.prototype);
console.assert(p1.constructor.prototype == Object.getPrototypeOf(p1));

const p2 = Object.create(p1);
console.assert(p1 == Object.getPrototypeOf(p2));
console.assert(!p2.hasOwnProperty("constructor") && p2.constructor == p1.constructor);
...