es6中实现类(class)和类(class)的继承(extends)

简介

extends 关键词被用在类声明或者类表达式上,以创建一个类是另一个类的子类。Class 可以通过 extends 关键字实现继承。

语法

1
class ChildClass extends ParentClass { ... }

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//父类
class Polygon {
// ..and an (optional) custom class constructor. If one is
// not supplied, a default constructor is used instead:
// constructor() { }
// 只能有一个 constructor 不能多次定义、如果没有声明 默认定义 constructor() { }
constructor(height, width) {
this.name = "Polygon";
this.height = height;
this.width = width;
}

// Simple class instance methods using short-hand method
// declaration
sayName() {
ChromeSamples.log("Hi, I am a ", this.name + ".");
}

sayHistory() {
ChromeSamples.log(
'"Polygon" is derived from the Greek polus (many) ' + "and gonia (angle)."
);
}

// We will look at static and subclassed methods shortly
}
class Square extends Polygon {
constructor(length) {
// 这里把length传参给父类的构造方法
// 作为父类Polygon的宽和高
super(length, length);
// 备注:在衍生类中使用this前必须先调用super()方法
// 忽视这一点将会导致一个引用错误
this.name = "Square";
}

get area() {
return this.height * this.width;
}

set area(value) {
this.area = value;
}
}
let s = new Square(5);
s.sayName();
ChromeSamples.log("The area of this square is " + s.area);

声明一个父类 Polygon,constructor(构造函数中)创建了三个属性 name,height,width,

Square通过extends关键字,继承了Polygon类中的所有属性和方法。
子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。
检验Square是否继承Polygon可以通过 Object.getPrototypeOf()

1
Object.getPrototypeOf(Square) === Polygon; // true

super 关键字

super 这个关键字,既可以当作函数使用,也可以当作对象使用。

子类的构造函数必须执行一次 super 函数,代表调用父类的构造函数,不然会报错。

super 内部的 this 指的是 Square,相当于 Polygon.prototype.constructor.call(this);
作为函数时,super()只能用在子类的构造函数之中,用在其他地方就会报错

1
2
3
4
5
6
7
8
9
10
11
12
13
class Polygon {
constructor() {
console.log(new.target.name);
}
}
class Square extends Polygon {
//super(); // 报错
constructor() {
super();
}
}
new Polygon(); // Polygon
new Square(); // Square

super 可以作为对象在普通函数中使用,指向父类的原型对象,在静态方法中,指向父类

类的 prototype 属性和proto属性

在 JavaScript 中,每一个对象都有proto属性,指向对应的构造函数的 prototype 属性。