js继承
继承就子类能自动从父类获得属性和方法的机制,我理解它是不劳而获。
继承的概念来自面向对象的编程语言,而js本质上不是一门面对对象的,所以它的继承其实也不太严谨,实现的方式非常多,名称也非常难记忆,开发中也少用到。 不像java中的继承,简单明了,代码里处处使用。
先把问题聚焦下: 如何从已有的构造器Father出发,创建一个新的构造器Son,让 new Son 得到的对象也能访问Father上的属性和方法?
分两ES5和ES6来说。
es5的继承
光看名字:原型链继承,构造函数继承,组合式,原生式,寄生式,寄生组合式继承... 晕不晕。初学好好体会一下是不错的(java在旁边叉着腰靠着窗,笑意盈盈看者)
8种继承:zhuanlan.zhihu.com/p/110175302
我下面写的这种与上面的都不同(但是没有支持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 ...')
}
}
开发中的继承
- react的类组件
class Com extends React.Component {}
- TS的interface
interface Ison extends IFather {}
其实我已近很久没有在业务代码中见过继承了
代码参考: es5的继承