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

阅读 3.4k
5 个回答

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

SubType.prototype = new SuperType(); 

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

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 是不成立的

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】

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

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

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

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

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题