为什么 obj.constructor.prototype 并不总是等于 obj.__proto__?

Why is obj.constructor.prototype not always equal to obj.__proto__?

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__ 之间关系的理解。提前致谢!

这仅适用于使用 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);