js经典继承中,为什么使用的是借用构造函数,而不是直接使用构造函数?

如题,最近在翻红宝书的时候发现了一个疑惑的问题。
在6.3继承的篇章中提到了组合继承,其解释如下:

clipboard.png

而后还有一段补充其在js中的地位为最常用的继承模式:

clipboard.png

那么问题来了,原型链,构造函数大家估计都知道是什么,那么借用构造函数呢?

那么给出一段借用构造函数的例子:

function SuperType(){
    this.colors = ["red", "blue", "green"];
} 
 
function SubType(){
    //继承了 SuperType 
    SuperType.call(this);
} 
 
var instance1 = new SubType(); instance1.colors.push("black");
alert(instance1.colors);    //"red,blue,green,black" 
 
var instance2 = new SubType();
alert(instance2.colors);    //"red,blue,green"

而使我感到疑惑的便是为何是借用构造函数,如上面代码中,父类中调用超类给子类添加子类私有的属性。
为什么这个不能使用构造函数做呢?
明明构造函数一样可以实现,并且构造函数比借用构造函数结构还要简单点。
改为构造函数的例子,效用与借用构造函数是一样的:

function SubType() {
  this.colors = ["red", "blue", "green"];
}

var instance1 = new SubType();
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black" 

var instance2 = new SubType();
alert(instance2.colors); //"red,blue,green"

所以我再强调一下我的问题:为什么组合继承中要使用借用构造函数,而不是直接使用构造函数?在我看来构造函数比借用构造函数简单,并且功能一致。

阅读 2.3k
2 个回答

不不,组合继承和构造函数根本就是两个概念,一个是为了继承,一个单纯只是为了实例化,概念都不一样。
组合继承为什么要使用借用构造函数?因为如果都是用原型链继承,当我更子类上继承于父类的属性,特别是引用属性的时候,也会连同父类上的那个属性一起修改了,引起误操作。
如果都是用借用构造函数,由于借用构造函数继承的属性,只是基于父类的属性的拷贝,跟父类没有任何联系,所以当你需要更改某个使用借用构造函数继承的属性的时候,会发现只是更改父类并不起效果,要全部修改,有多少子类你就要去修改多少次。此外,如果全部使用借用构造函数,当父类方法属性较多时,会造成不必要的内存开销。

两者独立还叫什么继承
如果改动 父类中的东西 比如删除red字段 直接使用构造函数的子类 两者是没有关系的

function SuperType(){
    this.colors = ["red", "blue", "green"];
} 
 
function SubType1(){
    //继承了 SuperType 
    SuperType.call(this);
    this.colors.push("black")
}
function SubType2(){
    //继承了 SuperType 
    SuperType.call(this);
    this.colors.push("white")
}

如果有一天修改colors 删除red 那么只需修改父类:

function SuperType(){
    this.colors = ["blue", "green"];
}

如果都是独立的 那有100个子类 就要修改100

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