Javascript实现继承的多种方式

419 阅读2分钟

构造继承(构造继承有多种实现方式)

借用构造函数的技术(有时候也叫做伪造对象或经典继承)。这种技术的基本思想相当简单,即在子类构造函数内部调用超类构造函数。

冒充继承

function Person(name, age){
    this.name = name
    this.age = age 
    this.showName = function(){
        console.log('我是' + name)
    }
}

function Child(){
    this.temp = Person // 创建一个自身缓存函数, 并将父类函数作为它的值
    this.temp('ysg', 18) // 执行缓存函数,即执行父类函数
    delete this.temp // 删除缓存函数
}

绑定this方式实现

function Child(){
    Person.bind(this)('ysg', 18) // 绑定this到Person运行环境执行函数
}

call方式实现

function Child(){
    Person.call(this, 'ysg', 18)
}

apply方式实现

function Child(){
    Person.apply(this, ['ysg', 18])
}

原型继承

function Person(name, age){
    this.name = name
    this.age = age
}

Person.prototype.showName = function(){
    console.log(this.name)
}

function Student(){}
Student.prototype = new Person('ysg', 18)
const stu = new Student()
stu.showName()

组合方式

组合继承,有时候也叫做伪经典继承,指的是将原型链和借用构造函数的技术组合到一块,从而发挥两者之长的一种继承模式。

其背后的思路是使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。 这样,即通过在原型上定义方法实现了函数的复用,又能够保证每个实例都有它自己的属性。

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

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

function SubType(name, age){
    // 继承属性
    SuperType.call(this, name)
    this.age = age
}

// 继承方法
SubType.prototype = new SuperType()
SubType.prototype.constructor = SubType

寄生继承

寄生式继承是与原型式继承紧密相关的一种思路,并且同样也是由克罗克福德推而广之。寄生式继承的思路与寄生构造函数和工厂模式类似,即创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后再像真的是它做了所有工作一样返回对象。

function createAnother(original) {
    const clone = Object(original) // 通过调用函数来创建一个新对象
    clone.sayHi = function(){ // 以某种方式来增强这个对象
        alert('hi')
    }
    return clone // 返回这个对象
}

const person = {
    name : 'ysg',
    age : 18
}

const anotherPerson = createAnother(person)
anotherPerson.sayHi()

寄生组合方式

寄生组合式继承,即通过借用构造函数来继承属性, 通过原型链的混成形式来继承方法。

其背后的基本思想是:不必为了指定子类型的原型而调用超类型的构造函数, 我们所需要的无非就是超类型原型的一个副本而已。 本质上,就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型。

function inheritPrototype(subType, superType){
    const prototype = Object(superType.prototype) // 父函数原型创建副本
    prototype.contructor = subType 
    subType.prototype = prototype // 子函数的的原型
}

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

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


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

inheritPrototype(SubType, SuperType)


ES6的extends实现继承

参考链接

zhuanlan.zhihu.com/p/36340941