「这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战」
前言
👉 上期回顾:JavaScript里Class类的基本介绍
本节主要来说说类里的继承,让我们先从一个常见的示例开始
extends关键字
假如当前创建了一个动物类Animal
class Animal {
constructor(name) {
this.speed = 0;
this.name = name;
}
run(speed) {
this.speed = speed;
console.log(`${this.name} 奔跑的速度是 ${this.speed}.`);
}
stop() {
this.speed = 0;
console.log(`${this.name} 停止奔跑`);
}
}
let animal = new Animal("My animal");
然后现在又想另外创建一个小狗类Dog,因为小狗Dog是动物Animal,所以,【小狗】应该是基于【动物】的,需要能够访问【动物】类的方法,使【小狗】可以做“一般”动物可以做的事情。
这个时候你就可以用到类继承了,
📖 关键字extends ,
📖 基本语法class Child extends Parent
现在来试试创建一个继承自【动物】的【小狗】
class Dog extends Animal {
speak() {
console.log(`${this.name} 在叫!`);
}
}
🍉 运行结果:
可以看到【小狗】的对象除了可以访问到自己的speak()方法,还可以访问到【动物】里的run() 和 stop()等方法。
💡 示例分析:
在内部,关键字 extends 使用了旧的原型机制进行工作。
它将 Dog.prototype.[[Prototype]] 设置为 Animal.prototype。所以,如果在 Dog.prototype 中找不到一个方法,JavaScript 就会从 Animal.prototype 中获取该方法。
传送门:原型的继承
重写父类的方法
现在我们在来思考一个问题,【动物】中有stop()方法,如果我在【小狗】里也写一个stop()方法,那么执行的是哪个呢?
🍉 运行结果:
从运行结果可以看到,【自己】的方法执行的优先级比【父级】的更高,但是有的时候,我们只是希望在【父类】方法的基础上调整或者扩展,并不想完全替换掉【父类】的方法,那这要怎么实现呢?
Class 为此提供了 "super" 关键字。
- 执行
super.method(...)来调用一个父类方法。 - 执行
super(...)来调用一个父类 constructor(只能在我们的 constructor 中)。
现在我们再来试一试,让小狗在【停止奔跑】时,【叫】一声
class Dog extends Animal {
stop() {
super.stop(); // 调用父类的 stop
console.log(`${this.name} 叫了一声!`);
}
}
🍉 运行结果:
重写constructor
最后在来看一个问题,可以发现我们上面的Dog都没有自己的constructor 。
根据 规范,如果一个类扩展了另一个类并且没有 constructor,那么将生成下面这样的“空” constructor:
class Dog extends Animal {
// 为没有自己的 constructor 的扩展类生成的
constructor(...args) {
super(...args);
}
}
它调用了父类的 constructor,并传递了所有的参数。如果我们没有写自己的 constructor,就会出现这种情况。
现在我们给Dog添加一个自定义的constructor来看看
class Animal {
constructor(name) {
this.speed = 0;
this.name = name;
}
}
class Dog extends Animal {
constructor(name, earLength) {
this.speed = 0;
this.name = name;
this.earLength = earLength;
}
}
let dog = new Dog("Dog", 10);
🍉 运行结果:
可以看到,此时尝试新建一个dog时,报错了。
这是因为:**继承类的 constructor 必须调用 super(...),并且 一定要在使用 this 之前调用。**所以想让Dog的 constructor 正常工作,它需要在使用 this 之前调用 super()。
🎨 示例:
...
class Dog extends Animal {
constructor(name, earLength) {
super(name); //关键
this.name = name;
this.earLength = earLength;
}
}
...
🍉 运行结果:
参考资料:
WIKI Class (computer programming)
🎨【点赞】【关注】不迷路,更多前端干货等你解锁
往期推荐