【问题标题】:Why is obj.constructor.prototype not always equal to obj.__proto__?为什么 obj.constructor.prototype 并不总是等于 obj.__proto__?
【发布时间】:2020-08-01 14:50:40
【问题描述】:
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__之间关系的理解。提前致谢!

【问题讨论】:

    标签: javascript prototypal-inheritance


    【解决方案1】:

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

    【讨论】:

    • 但是,我不明白console.log(p2.constructor.prototype === p1.__proto__); 怎么变成true?在原型继承方面,我对 p1p2 之间的关系感到困惑。
    • @GeniusGo p2.constructor 继承自 p1.constructor(又继承自 Product.prototype.constructor)。
    • 还有一个问题,我知道p1.__proto__指向p1.constructor.prototype,但是p2.__proto__指向哪里呢?
    • @GeniusGo p1 - 见const p2 = Object.create(p1); console.assert(p1 == Object.getPrototypeOf(p2));
    • 哦,明白了!!非常感谢@Bergi!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    • 1970-01-01
    • 2020-09-23
    相关资源
    最近更新 更多