JS常见继承方式解析


原型链继承


// 1 用父类构造函数构建一个父类空对象

// 2 将子类构造函数的prototype指向新建的对象

// 3 添加子类特有的方法

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

function SubType(){
    this.subproperty = false
}

SubType.prototype = new SuperType()     //构建prototype

SubType.prototype.getSubValue = function(){
    return this.subproperty
}

缺陷:

1 若父类对象包含引用类型数据,该数据会被所有子类对象共享

//关于父类对象包含引用类型数据的测试
function SuperType(){
    this.arr = ['1', '2', '3']
}
SuperType.prototype.changeArr = function(char){
    this.arr.push(char)
}

function SubType(){

}

SubType.prototype = new SuperType()

SubType.prototype.getArr = function(){
    console.log(this.arr)
}

const ins1 = new SubType()
const ins2 = new SubType()

ins1.changeArr('4')
ins2.getArr()   //['1', '2', '3', '4']

2 创建子类对象时不能给父类构造函数传参

借用构造函数继承

// 通过call/apply方法在子类构造函数中调用父类构造函数
function SuperType(name){
    this.name = name
}

function SubType(name, age){
    SuperType.call(this, name)
    this.age = age
}

缺陷:

父类方法无法重用,且定义在父类原型上的方法对子类不可见

组合继承

// 前面两种方法的结合,使用父类对象最为原型继承方法,使用父类构造函数获得数据

function SuperType(name){
    this.name = name
    this.arr = [1, 2, 3]
}
SuperType.prototype.sayName = function(){
    console.log(this.name)
}

function SubType(name, age){
    SubType.call(this, name)
    this.age = age
}

SubType.prototype = new SuperType()

SubType.prototype.sayAge = function(){
    console.log(this.age)
}

缺陷:

构建原型对象时多调用了一次父类构造函数,导致原型对象带上了无意义的父类数据

组合寄生式继承


// 使用空对象作为原型实现继承,避免了原型继承的缺陷

function object(target){
    function temp(){}
    temp.prototype = target
    return new temp()
}

function inherit(subType, superType){
    let prototype = object(superType.prototype)
    prototype.construtor = subType
    subType.prototype = prototype
}

function SuperType(name){
    this.name = name
}
SuperType.prototype.sayName = function(){
    console.log(this.name)
}

function SubType(name, age){
    SuperType.call(this, name)
    this.age = age
}

inherit(SubType, SuperType)

SubType.prototype.sayAge = function(){
    console.log(this.age)
}

参考《JS高级程序设计》


Author: Maple
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source Maple !
  TOC