ES6之class类的补充

1. 属性表达式

类的属性名,可以采用表达式。给大家举一个例子,代码如下:

1
2
3
4
5
6
7
8
9
10
11
let propName = "getMethod";
class Prop{
constructor(){
//...
}
[propName](){ // 此时Prop类的方法名getMethod是从“let propName = 'getMethod';”表达式得到的
console.log("I am prop_name");
}
}
let prop = new Prop();
prop.getMethod(); // I am prop_name

2. Class表达式

与函数一样,类也可以使用表达式的形式定义。

1
2
3
4
5
6
7
8
9
10
11
12
// 使用表达式定义了一个类
const Outer = class Inner{
getClassName(){
return Inner.name; // Inner在内部可以进行一个使用
}
};
// 注意:这个类的名字是Inner,但是Inner只是在Class的内部可以使用的,指代当前类
// 在Class外部,这个类只能使用Outer引用

let outer = new Outer();
console.log(outer.getClassName()); // Inner
Inner.name; // Inner在外部使用会报错,报错信息为:Inner is not defined

此时我们可以看到Inner只在Class内部有定义,在外部使用会报错。此时,如果类的内部(Inner)没有用到的话,可以省略Inner,因此就可以写成下面这种形式:

1
const Outer = class{};

采用Class表达式,可以写出立即执行的Class。代码如下:

1
2
3
4
5
6
7
8
9
let person = new class{
constructor(name){
this.name = name;
}
sayName(){
console.log(this.name);
}
}("daipi173");
person.sayName(); // "daipi173"

在上面的代码中,person是一个立即执行的类的实例。

3. 严格模式

类和模块的内部,默认就是严格模式,所以不需要使用use strict指定运行模式。只要你的代码写在类或模块之中,就只有严格模式可用。考虑到未来所有的代码,其实都是运行在模块之中,所以 ES6 实际上把整个语言升级到了严格模式。

4. 类不存在变量提升

1
2
new Person(); // ReferenceError: Person is not defined
class Person{}

在上面代码中,Person类使用在前,定义在后,此时这样使用就会报错。其原因是因为ES6不会把类的声明提升到代码头部。
为什么要说“类不存在变量提升”?
其原因是因为和继承有关,必须保证子类在父类之定义。

1
2
3
4
5
6
7
{
let Parent = class {};
class Child extends Parent{
}
} // 代码不会报错
// 因为Child继承Parent的时候,Parent已经被定义了
// 但是'如果存在class类的一个提升',上面的代码就会报错,因为class类会被提升到代码头部,而let命令是不会提升的,所以导致Child继承Parent的时候,Parent还没有定义。

5. name属性

由于本质上,ES6 的类只是 ES5 的构造函数的一层包装,所以函数的许多特性都被Class继承,包括name属性。

1
2
class Person{}
console.log(Person.name); // Person

注意:name属性总是返回紧跟在class关键字后面的类名。

6. Generator方法

如果某个方法之前加上星号(*),就表示该方法是一个 Generator 函数。在之前的笔记中我分享过Generator的相关笔记,附上我之前的笔记链接:http://blog.chanke.xyz/daipi173/1669/es6zhishengchengqigenerator/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Person{
constructor(...args){
this.args = args;
}
*[Symbol.iterator](){
for(let arg of this.args){
yield arg;
}
}
}

for(let x of new Person("xiaohong","xiaoming","xiaoli")){
console.log(x);
}
// 控制台打印内容:
// xiaohong
// xiaoming
// xiaoli

在上面的代码中,Person类的Symbol.iterator方法前有一个星号,表示该方法是一个 Generator 函数。Symbol.iterator方法返回一个Person类的默认遍历器,for of循环会自动调用这个遍历器。