js03-js中的继承

264 阅读2分钟

js继承

继承就子类能自动从父类获得属性和方法的机制,我理解它是不劳而获

继承的概念来自面向对象的编程语言,而js本质上不是一门面对对象的,所以它的继承其实也不太严谨,实现的方式非常多,名称也非常难记忆,开发中也少用到。 不像java中的继承,简单明了,代码里处处使用。

先把问题聚焦下: 如何从已有的构造器Father出发,创建一个新的构造器Son,让 new Son 得到的对象也能访问Father上的属性和方法?

分两ES5和ES6来说。

es5的继承

光看名字:原型链继承,构造函数继承,组合式,原生式,寄生式,寄生组合式继承... 晕不晕。初学好好体会一下是不错的(java在旁边叉着腰靠着窗,笑意盈盈看者)

8种继承:zhuanlan.zhihu.com/p/110175302

6种继承:juejin.cn/post/684490…

我下面写的这种与上面的都不同(但是没有支持instance of),可以参考下思路:

如何继承属性?

在子类构造器中调用父构造器方法,并使用call来修改this。

function Father (firstName) {
    this.firstName = firstName
}

function Son(firstName, age) {
   // 执行Father函数,用当前的this来修改Father内的this,并传入参数
   // 借用父构造器给自己添加属性
   Father.call(this, firstName)
   this.age = age
}

const s1 = new Son('张', 18)
console.log(s1.first) // 张
console.log(s1.age) // 18

如何继承方法

目标: 让子构造器生成的对象也能拥有父构造器上的方法

思路: 直接浅拷贝即可

function Father(firstName) {
    this.firstName = firstName
}

Father.prototype.say = function () {
    console.log('Father say....')
}

function Son(firstName, age) {
    // 1.继承属性
    // 执行Father函数,用当前的this来修改Father内的this,并传入参数
    // 借用父构造器给自己添加属性

    Father.call(this, firstName)

    // 这是子构造器自己的属性
    this.age = age

}

Son.prototype.run = function () {
    console.log('Son run ...')
}

// 2. 继承方法

// 浅拷贝,直接共用方法。如果有自己的方法就用自己的,否则就使用父构造器的

for (let fn in Father.prototype) {
    console.log(fn)
    if (!Son.prototype[fn])
        Son.prototype[fn] = Father.prototype[fn]

}

上面的代码实现就有一个缺陷:不支持 子类实例 instanceof 父类构造器 === true 也就是两个构造器之间没有任何关联,代码运行结束之后,向父类构造器上添加新属性,子构造器并不能访问到。

es6中的继承

直接使用 class extends,super等关键字即可

class Father {
    constructor(firstName) {
        this.firstName = firstName
    }
    say() {
        console.log('Father say....')
    }
}

class Son extends Father {
    constructor(firstName, age) {
        super(firstName) // 调用父类构造函数
        this.age = age
    }

    run() {
        console.log('Son run ...')
    }
}

开发中的继承

  1. react的类组件
class Com extends React.Component {}
  1. TS的interface
interface Ison extends IFather {}

其实我已近很久没有在业务代码中见过继承了

代码参考: es5的继承