ES6 class
本文最后更新于 2024年6月7日 下午
前言
class是ES6中引入的语法糖,其中的绝大部分的功能都可以使用ES5的方法做到。class可以看作是构造函数的另一种写法。
1 | |
class中的方法
在class中定义方法,就相当于在原型对象上定义方法。
1 | |
constructor方法
1 | |
构造函数本身起到构造作用,使用class方法后,需要在类中引入一个constructor方法,该方法必须在“类”中存在,如果没有显式定义,引擎会自动为其添加一个空的constructor方法。
constructor默认返回实例对象即this,当然也可以如构造函数一样返回另外一个对象。

如上图,当constructor方法返回一个对象,new命令执行后返回的就是该对象,当constructor有返回值,但是返回的不是一个对象时,默认返回的还是this实例对象。
class必须使用new命令调用,不能如构造函数般地直接调用。
constructor中定义的实例对象的属性,可以使用一种新的写法:
1 | |
等同于:
1 | |
静态
静态方法
在class中的方法前加上static关键字,就说明该方法是静态方法,静态方法不会被实例对象继承,需要通过类来直接调用,静态方法中的this关键字指向类,而不是实例对象。
父类的静态方法可以被子类继承。
静态属性
定义在类上的属性。
1 | |
其他
new.target
- 构造函数中使用:返回
new命令调用的构造函数,如果构造函数不是使用new命令或者Reflect.construct()进行调用,则返回undefinded。 - 类内部调用:返回当前的类。
class注意事项
class内部默认采用“严格模式”。- 不存在“类”提升。
- 方法名前加
*,表示这是一个Generator方法。 this指向类的实例。
class 继承
class中的继承是通过extend关键字实现的。
但是ES6中的继承机制与ES5不同。
ES5中是先存在子类的this对象,然后将其绑定至父类的构造函数上,执行父类的构造函数,然后再执行子类的构造函数,之后再将子类的原型对象指向父类,将原型中的构造函数指向自己的构造函数。
ES6则是需要调用父类的构造函数,附带作用是生成一个this对象,之后才能在this上进行添加与修改。所以class中进行继承,在子类的构造函数中若是想使用this关键字,需要先调用super方法。
Super关键字
super关键字有两种用法:
-
作为函数:代表父类的构造函数,虽然代表父类的构造函数,但是调用父类的构造函数时,其中的this却指向子类实例,super作为方法使用时,只能出现在子类的构造函数中。
1
2
3
4
5
6
7
8
9
10
11
12class A {
constructor() {
console.log(new.target.name);
}
}
class B extends A {
constructor() {
super();
}
}
new A() // A
new B() // B -
作为对象:
- 指向父类的原型对象:可以使用其调用父类原型对象上的方法,但是需要注意此时,方法中的this也指向子类实例。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21class A {
constructor() {
this.x = 1;
}
print() {
console.log(this.x);
}
}
class B extends A {
constructor() {
super();
this.x = 2;
}
m() {
super.print();
}
}
let b = new B();
b.m() // 2- 指向父类:可以使用其调用父类上的静态方法,此时this指向子类而不是子类实例。
prototype属性和__proto__属性
class 同时拥有这两个属性:
1 | |
-
从构造函数的角度出发:
B作为构造函数,B对应的原型对象的原型肯定是构造函数A的原型对象,这是在ES5中就成立的。1
B.prototype.__proto__ = A.prototype; -
但是
ES6中引入了静态方法,B继承了A的静态方法,A、B可以直接调用静态方法,此时可以将其看作一个特殊的对象,那么对象是存在__prop__方法的,这时B的原型即为A。1
B.__proto__ = A;