javascript原型链问题,为什么Child.prototype = new Person();就可以改变原型指向?

在看《JavaScript高级程序设计(第3版)》原型链这块,有一些疑问。

当没有继承时:

function SuperType() {
    this.property = true;
}
SuperType.prototype.getSuperValue = function () {
    return this.property;
};

原型的图示如下:
image.png

当有继承时:

function SuperType() {
    this.property = true;
}
SuperType.prototype.getSuperValue = function () {
    return this.property;
};
////////////////////////////
// 加了如下代码
///////////////////////////
function SubType() {
    this.subproperty = false;
}
SubType.prototype = new SuperType(); // **主要是这句**
SubType.prototype.getSubValue = function () {
    return this.subproperty;
};

变成了这样。
image.png

但是SubType.prototype = new SuperType()这行代码,只是改了SubType中prototype的指向,不应该是向下图这样吗?4号线是怎么出来的?它不应该是将3号线改成7号线吗?像下图这样吗?
image.png

已解决 悬赏分:50 - 解决时间 2022-01-04 22:47
反对 0举报 0 收藏 0

回答5

最佳
  • @

    3275842234-5ea917b87ffbc.png
    你理解的没有什么错,但是忽略了我用红圈圈起来的两个框是有关联的,他们两个在

    SubType.prototype = new SuperType(); 

    这句代码的影响下其实是同一个对象.你把这两个框合并起来图就和上面的一样了.

    支持 0 反对 0 举报
    2022-01-04 03:47
  • @

    SubType.prototype = new SuperType()
    这一句可以理解成以下

    let obj = new SuperType()
    SubType.prototype = obj

    这个 obj 其实就是你图1中的 superType 实例


    还有,你要搞清楚_proto_是一个对象的属性,指向它构造函数的原型对象。

    1、现在 SubType 的原型对象是 obj,它的 _proto_ 属性,指向该原型对象的构造函数的原型对象,
    这个构造函数就是 SuperType。

    obj.__proto__ === SuperType.prototype

    即: SubType.prototype._proto_ 指向 SuperType.prototype, 所以 4 是这样来的

    2、SubType.prototype 是指向 SuperType 的实例对象,而不是实例对象的_proto_属性, 所以你的 7 是不成立的

    支持 0 反对 0 举报
    2022-01-04 05:12
  • @
    function SuperType() {
        this.property = true;
    }
    SuperType.prototype.getSuperValue = function () {
        return this.property;
    };
    ////////////////////////////
    // 加了如下代码
    ///////////////////////////
    function SubType() {
        this.subproperty = false;
    }
    var __temp__prototype__ = new SuperType();
    SubType.prototype = __temp__prototype__ // **主要是这句**
    SubType.prototype.getSubValue = function () {
        return this.subproperty;
    };
     var subTypeInstance = new SubType();
     // SubType实例的__proto__指向一个SuperType实例,这个实例作为SubType的原型对象
      console.log('subTypeInstance.__proto__ is SubType.prototype',subTypeInstance.__proto__===SubType.prototype);
      console.log('SubType.prototype is __temp__prototype__(SuperType instance)',SubType.prototype===__temp__prototype__);
     console.log('subTypeInstance.__proto__ is __temp__prototype__(SuperType instance)',subTypeInstance.__proto__===__temp__prototype__);
     console.log('SubType.prototype is __temp__prototype__(SuperType instance)',SubType.prototype === __temp__prototype__);
    
     

    SubType实例的__proto__ 指向SubType原型对象【3】,SubType原型对象是SuperType实例【2】,SuperType实例的__proto__ 指向SuperType原型对象【4】,SuperType原型对象就是个普通Object【1】

    支持 0 反对 0 举报
    2022-01-04 05:57
  • @

    你画的两个图的理解都没问题,个人觉得你的迷茫是因为没有理解function.prototype属性和obj.__proto__属性

    • prototype: 属性是函数特殊有的属性,指向函数的原型对象
    • __proto__: 属性是非标准属性,是浏览器自己实现的一个属性,指向对象的构造函数的原型对象

    JS原型链可以看这篇文章,很短,但是能讲明问题

    支持 0 反对 0 举报
    2022-01-04 06:43
  • @

    注意 new 操作符实际上是创建了一个继承构造函数的 prototype的新对象,例如 var foo = new Foo(...),foo.prototype 指向 Foo.prototype, 而SubType.prototype = new SuperType() 这里 SubType.prototype 指向 SuperType.prototype

    支持 0 反对 0 举报
    2022-01-04 08:13