javascript中的继承

javascript中的继承

1、原型链继承:
function Parent() {
    this.familyName = 'Xu'
}
Parent.prototype.getFamilyName = function() {
    return this.familyName
}

function Children() {
    this.firstName = 'Ryan'
}

// 原型链继承
Children.prototype = new Parent()
Children.prototype.constructor = Children

let children1 = new Children()

children1.familyName // Xu
children1.getFamilyName() // Xu

缺点:当父类中含有引用类型的属性时,利用父类生成的所有实例都会共享该引用数据类型的属性,即当在某个实例中修改继承于父类的引用类型属性值时,所有实例都将受到影响;

2、借用构造函数继承:
function Parent() {
    this.familyName = 'Xu'
}
Parent.prototype.getFamilyName = function() {
    return this.familyName
}

function Children() {
    // 借用构造函数继承
    Parent.call(this)
    this.firstName = 'Ryan'
}

let children1 = new Children()
children1.familyName // Xu
children1.getFamilyName() // Uncaught TypeError: children1.getFamilyName is not a function

let children2 = new Children()
children2.familyName // Xu
children2.familyName = 'X'
children2.familyName // X
children1.familyName // Xu

优点:避免了父类中引用类型属性被所有实例共享,从而解决了原型上引用类型属性被修改的问题
缺点:只能继承父类本身的属性和方法,不能继承其原型上的属性和方法。

3、组合继承:

组合继承就是将原型链继承与借用构造函数继承结合起来。

function Parent() {
    this.familyName = 'Xu'
}
Parent.prototype.getFamilyName = function() {
    return this.familyName
}

function Children() {
    // 借用构造函数继承
    Parent.call(this)
    this.firstName = 'Ryan'
}

// 原型链继承
Children.prototype = new Parent()
Children.prototype.constructor = Children

let children1 = new Children()
children1.familyName // Xu
children1.getFamilyName() // Xu
4、原型式继承:

原型式继承是将父类对象赋值给一个空的构造函数的原型,然后返回一个空的构造函数的实例来实现父类属性和方法的继承。

  • 手动实现原型式继承:
// 原型式继承
function object(obj){
    function F() {}
    F.prototype = obj
    return new F()
}

let parent = {
    familyName: 'Xu',
    getFamilyName: function (){
        return this.familyName
    }
}

let children1 = object(parent)
children1.familyName // Xu
children1.getFamilyName() // Xu
  • 使用ES5中的Object.create()来实现原型式继承:
let parent = {
    familyName: 'Xu',
    getFamilyName: function (){
        return this.familyName
    }
}

// Object.create()实现原型式继承
let children1 = Object.create(parent)

children1.familyName // Xu
children1.getFamilyName() // Xu
5、寄生式继承:

寄生继承是一种在原型式继承的基础上通过为子类添加属性和方法来增强子类对象的继承方法。

let parent = {
    familyName: 'Xu',
    getFamilyName: function (){
        return this.familyName
    }
}

// 寄生式继承
function parasiticInherit(superClass){
    let children = Object.create(superClass)
    // 通过为子类添加属性或方法来增强对象
    children.firstName = 'Ryan'
    return children
}

let children1 = parasiticInherit(parent)

children1.familyName // Xu
children1.getFamilyName() // Xu
6、寄生组合继承:

寄生组合继承是一种融合了寄生式继承中的原型式继承增强对象以及组合继承中的原型链继承借用构造函数继承的继承方法。

function Parent() {
    this.familyName = 'Xu'
}
Parent.prototype.getFamilyName = function () {
    return this.familyName
}

function parasiticInherit(subClass, superClass){
    // 原型式继承,创建父类原型副本对象
    let superClassPrototypeClone = Object.create(superClass.prototype)
    // 增强新建对象
    superClassPrototypeClone.constructor = subClass
    // 原型链继承,将新建的对象赋值给子类
    subClass.prototype = superClassPrototypeClone
}

function Children() {
    // 借用构造函数继承
    Parent.call(this)
    this.firstName = 'Ryan'
}

parasiticInherit(Children, Parent)

let children1 = new Children()

children1.familyName // Xu
children1.getFamilyName() // Xu
7、ES6中的继承:

ES6中使用class创建构造函数,使用extends来实现继承。

class Parent {
    constructor() {
        this.familyName = 'Xu'
    }
    getFamilyName() {
        return this.familyName
    }
}

// 使用extends关键字实现继承
class Children extends Parent {
    constructor() {
        // 子类继承时中必须调用super方法,否则创建实例时会报错,这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工
        // super虽然代表了父类的构造函数,但返回的结果为子类的实例,即在super内部中this是指向子类的,因此,super()的作用相当于superClass.prototype.constructor.call(this)
        super()
        this.firstName = 'Ryan'
    }
}

let children1 = new Children()
children1.familyName // Xu
children1.getFamilyName() //Xu
参考文献:

[1] 【前端词典】继承(二) - 回的八种写法·面试必问
[2] JavaScript常用八种继承方案

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值