js里面的继承方式回顾

99 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第10天,点击查看活动详情

今天我们来一起回顾一下js里面的几种继承。

js中的继承方式有哪些?

  • 原型链继承
  • 构造函数继承
  • 组合继承
  • 原型式继承
  • 寄生式继承
  • 寄生式组合继承

接下来我们展开看一下

原型链

原型链继承是js中主要的继承方式

缺点:
原型中包含引用值,该值会在多个实例共享。比如说:

function SuperType(){
    this.color=['red','yellow']
}
function SubType(){}
SubType.prototype=new SuperType()
let instance1 = new SubType()
let instance2 = new SubType()
instance1.color.push('green')
console.log(instance2.color)

因此属性通常会在构造函数中定义。不会在原型上面定义。

构造函数继承

构造函数继承可以解决上麦呢原型链继承中引用值的问题,实现思路为在子类的构造函数调用父类构造函数

function SuperType(){
    this.color=['red','yellow']
}
function SubType(){
    SuperType.call(this)
}
let instance1 = new SubType()
let instance2 = new SubType()
instance1.color.push('green')
console.log(instance1.color)
console.log(instance2.color)

构造函数继承也有缺点。 缺点:
必须在构造函数中定义方法,导致函数不能重用。子类不能访问父类原型上定义的方法。因此这种方法基本不会单独使用

组合继承

组合继承是将上面的两种继承方式结合起来。通过原型链继承原型上面的属性方法。通过构造函数继承实例属性。

function SuperType(){
}
function SubType(){
    SuperType.call(this)
}
SubType.prototype = new SuperType()

组合继承弥补了原型链继承和构造函数继承的不足。是js中使用最多的继承模式。而且 保留了instanceof操作符和isPrototypeOf方法。

缺点:

父类构造函数始终会被调用两次。

原型式继承

这种继承方式适用于:你有一个对象,想在他的基础上再创建一个新的对象。在js中 使用Object.create方法创建对象,便是原型式继承的规范化。

function create(o){
    function F(){}
    F.prototype = o
    return new F()
}
let originObj = {name:'123'}
let newObj = create(originObj)
console.log(newObj.name)
let createObj = Object.create(originObj)
console.log(createObj.name)

原型式继承适用于不需要单独定义构造函数,但是仍然需要再对象之间共享信息。
缺点:
他和原型链继承一样。对于引用类型的数据。在多个实例中会存在共享的情况。

寄生式继承

寄生式继承思路类似于工厂函数。创建一个实现继承的函数。然后在内部增强函数功能。

function create(o){
    function F(){}
    F.prototype = o
    return new F()
}
function clone(o){
    let cloneObj = create(o)
    cloneObj.test = function(){ console.log('hello') }
    return cloneObj
}
let originObj = {name:'123'}
let newObj = clone(originObj)
console.log(newObj.test())

寄生式继承也同样适用于不定义构造函数的场景。但是他也有缺点。

缺点:

通过寄生式继承给对象新加的函数是难以重用的。

寄生组合继承

寄生组合继承通过寄生式继承来继承父类原型。

function create(o){
    function F(){}
    F.prototype = o
    return new F()
}
function SuperType(){
    this.color=['red','yellow']
}
function SubTyoe(){
    SuperType.call(this)
}

function inheritPrototype(sub,sup){
    let prototype = create(sup.prototype)
    prototype.constructor = sub
    sub.prototype = prototype
}

inheritPrototype(SubType,SuperType)

let s1 = new SubType()

s1.color.push('234')
console.log(s1.color)
let s2 = new SubType()

寄生组合继承可以成为应用类型继承的最佳模式.

总结一下:原型链继承是js中主要的继承方式。组合继承用的最多。寄生组合继承最完美。