前言:es6之前在js中要实现继承,就必须要我们程序员在原型链上手动继承多对象的操作,但是结果往往存在漏洞,为解决这些问题,社区中出现了盗用构造函数、组合继承、原型式继承、寄生式继承等一系列继承方式,这都需要程序员对原型链有深入的认识。但是当es6出现,class关键字便一并将继承问题完美解决,且大大降低程序员的学习成本,只需要使用轮子即可。本文将会展开对类继承的叙述。
一、类的继承基础
在类中实现继承,需要使用关键字extends,使用之后就可以继承任何拥有[[constructor]]和原型的对象。这也就意味着使用extends,不止可以继承另一个类,同时也可以继承普通构造函数。
1 class Car{
2
3 }
4 class MyCar extends Car{
5
6 }
7 const firstCar = new MyCar();
8
9 console.log (firstCar instanceof Car); //true
10 console.log (firstCar instanceof MyCar); //true
11
12 function Person (){
13
14 }
15 class P1 extends Person{
16
17 }
18 const p = new P1();
19 console.log (p instanceof P1); //true
20 console.log (p instanceof Person); //true
在类和原型上定义的方法会被带到派生类(继承对象的对象)上。
1 class Car{
2 // 定义getName到Car原型上
3 getName(){
4 console.log (this);
5 }
6 // 定义setName到Car类自身上
7 static setName(){
8 console.log (this);
9 }
10 }
11 class MyCar extends Car{
12
13 }
14 const a = new Car;
15 const b = new MyCar();
16
17 a.getName(); //Car {}
18 b.getName(); //MyCar {}
19
20 Car.setName(); //class Car{}
21 MyCar.setName(); //class MyCar extends Car{}
二、构造函数与super()
派生类的方法可以通过super()关键字以实现原型的引用,原因在于super会调用父类构造函数,相当于super.constructor()。
1 class Person{
2 constructor(){
3 this.name = 'test'
4 }
5 }
6 class P1 extends Person{
7 constructor(){
8 super();
9 console.log (this.name);
10 }
11 }
12 new P1;
定义在父类上的静态方法也可以通过super调用继承类上定义的静态方法。
但是使用super时需要注意以下几点:
- super只能在派生类的构造函数和静态方法中使用
- 不能单独使用super,要么用来调用构造函数,要么用来引用静态方法
- 调用super()会调用父类构造函数,并将返回的实例赋值给this
- 在类构造函数中,不能在调用调用super()之前引用this
三、抽象基类
抽象基类可以用于在定义一个类时只需要供其他类继承而本身不用实例化的情况。
要实现抽象基类需要通过new.target,new.target保存通过new关键字调用的类或函数。
1 class Person{
2 constructor(){
3 //如果使用Person直接进行实例化会抛出错误
4 if(new.target === Person){
5 throw 'Person can,t be instantiated'
6 }
7 }
8 }
9 class P extends Person{
10
11 }
12 new P;
13 // new Person; 注释解开会导致报错
四、继承内置类型
es6之后,开发者可以通过类继承,轻松扩展内置类型。
1 // NewArray继承于Array,且扩展了Array属性
2 class NewArray extends Array{
3 // 洗牌算法
4 shuffle(){
5 for(let i = this.length-1;i>0;i--){
6 const j = Math.floor(Math.random()*(i+1));
7 [this[i],this[j]] = [this[j],this[i]];
8 }
9 }
10 }
11 let a = new NewArray(1,2,3,4,5);
12 console.log (a instanceof Array); //true
13 console.log (a instanceof NewArray); //true
14 console.log (a); //NewArray(5) [1, 2, 3, 4, 5]
15 a.shuffle();
16 console.log (a); //NewArray(5) [1, 4, 2, 3, 5]