js 继承 总结发言

对比不同的集中继承方式,在这里总结一下。可以参考:

《JS设计模式》笔记-继承之一

《JS设计模式》笔记-继承之二

类式继承:通过原型对象prototype 继承父类

存在这几个问题

  • 1:由于是原型对象进行的继承,继承时无法传参
  • 2:子类在实例化时,因为是公用的子类原型对象的属性,所以任何实例化对象对属性对修改都会影响到其他实例化对象。

构造函数继承:通过call来继承

由于核心原理是修改作用环境,在父类中执行一遍。所以存在两个问题

  • 1:无法继承原型对象
  • 2:父类 没有放在构造函数内部的属性也无法继承。如 fn.name = '小明'

组合继承:将构造函数继承和类式继承 融合起来

组合之后,构造函数内部由 构造函数继承处理,原型对象上由 类式继承处理。只存在一个问题:

  • 构造函数内的属性和方法,在 构造函数继承和类式继承时,分别执行了一遍。只是因为原型链的访问优先级,优先访问到构造函数继承 的方法。

原型继承:提供一个构造函数本身无属性的

升级版的类式继承,只不过构造函数内没有属性和方法,节省一部分开销。问题和类式继承一样。

  • 1:由于是原型对象进行的继承,继承时无法传参
  • 2:子类在实例化时,因为是公用的子类原型对象的属性,所以任何实例化对象对属性对修改都会影响到其他实例化对象。

寄生式继承:原型继承的基础上,进行扩展。

只是对原型继承的二次封装,扩展一些方法。问题没有改变。

  • 1:由于是原型对象进行的继承,继承时无法传参
  • 2:子类在实例化时,因为是公用的子类原型对象的属性,所以任何实例化对象对属性对修改都会影响到其他实例化对象。

寄生式组合式继承:寄生式继承和构造函数继承的组合。

对寄生模式进行再次封装,修改constructor指向问题,类式继承时过滤掉构造函数内部的属性和方法。通过构造函数继承,可以传参。

究极写法:

function inheritObject(o) {
    function F() {
    }
    F.prototype = o
    return new F()
}
function inheritPrototype(subClass, superClass) {
    var p = inheritObject(superClass.prototype)
    p.constructor = subClass
    subClass.prototype = p
}


function SuperClass(name) {
    this.name = name
}
SuperClass.prototype.getName = function () {
    console.log(this.name)
}
function SubClass(name) {
    SuperClass.call(this, name)
}
inheritPrototype(SubClass, SuperClass)

随机浏览