面向对象-继承

目录

方式一:原型链继承

方式二:构造函数继承

方式三:组合式继承

方式四:原型式继承

方式五:寄生式继承

方式六:寄生组合继承

ES6中的extends实现


方式一:原型链继承

// 原型链继承
let parentObj = {
    type: 'parentObj'
}
let a = new Object(parentObj)
// 修改原型链上的方法
a.__proto__.toString = "a改了toString方法"

无法传参;

无法多继承;

可以单继承,但属性共享。

方式二:构造函数继承

function Parent() {
    this.toString = function () {
        console.log(`Parent 的 toString`)
    }
    console.log('Parent')
}
Parent.prototype.parentSayHello = function () {
    console.log('Hello, I am parent')
}
function Child() {
    Parent.apply(this, Array.prototype.slice.call(arguments))
}
Child.prototype.childSayHello = function () {
    console.log('Hello, I am child')
}
const parent = new Parent()
const child = new Child('child')

 

 

每次创建实例,都需要调用父类的构造函数,会造成性能上的浪费;

子类使用apply后继承了父类中构造函数中属性和方法,但是原型链上的方法没有被继承。

方式三:组合式继承

// 组合继承
function Parent() {
    this.toString = function () {
        console.log(`Parent 的 toString`)
    }
    console.log('Parent')
}
Parent.prototype.parentSayHello = function () {
    console.log('Hello, I am parent')
}
function Child(tag) {
    Parent.apply(this, Array.prototype.slice.call(arguments))
    this.tag = tag
}
// 子类刚通过构造函数继承后,再去继承父类的原型链上的属性或方法
Child.prototype = new Parent()
Child.prototype.constructor = Child

Child.prototype.childSayHello = function () {
    console.log('Hello, I am child')
}
const child = new Child('child')

每次创建实例,都需要调用父类的构造函数,会造成性能上的浪费;

方式四:原型式继承

// 原型继承
let parentPO = {
    type: 'parentPO',
    toString: function () {
        console.log(`parentPO 的 toString`)
    }
}
let childPO = Object.create(parentPO)
childPO.toString = function() {
    console.log(`childPO 的 toString`)
}
childPO.__proto__.toString = function() {
    console.log(`childPO 的 toString`)
}

通过使用 Object.create() 方法实际是对父类的属性和方法浅拷贝,故属性共享。

方式五:寄生式继承

// 寄生继承
let parentPA = {
    type: 'parentPA',
    toString: function () {
        console.log(`parentPA 的 toString`)
    }
}

function ChildPA(){
    let clone = Object.create(parentPA)
    clone.selfToString = function () {
        console.log(`childPO 的 selfToString`)
    }
    return clone
}
const child = new ChildPA()

 

使用 Object.create() 方法对父类浅拷贝后,再添加私有方法。

方式六:寄生组合继承

// 寄生组合式继承
function inherits(Parent, Child){
    Child.prototype = Object.create(Parent)
    Child.prototype.constructor = Child
}
function Parent(){
    this.toString = function () {
        console.log(`parent 的 toString`)
    }
    console.log('parent')
}
Parent.prototype.parentSayHello = function () {
    console.log('Hello, I am parent')
}
function Child(){
    Parent.apply(this, Array.prototype.slice.call(arguments))
}
inherits(Parent, Child)

Child.prototype.childSayHello = function () {
    console.log('Hello, I am child')
}
const child = new Child()

将父类的属性或方法apply到当前子类,实现属性私有;

可以传参;

解决了构造函数多次调用的问题。

综合来说,寄生组合式继承是目前最优的继承方式。

ES6中的 extends实现

// ES6中的 extends 继承
class Person {
    constructor(hobby) {
        this.hobby = hobby
    }
    // Person.prototype.getHobby = function(){}
    getHobby = function () {
        console.log(this.hobby)
    }
}
class Student extends Person {
    constructor(hobby, age) {
        super(hobby)
        this.age = age
    }
}
const xiaoming = new Student('play game', 10)
xiaoming.getHobby()

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值