1
0
mirror of https://github.com/ruanyf/es6tutorial.git synced 2025-05-24 10:22:23 +00:00

docs(class): 加入 static block

This commit is contained in:
ruanyf 2021-09-02 08:29:12 +08:00
parent 4d9b22c6c8
commit 47dec55486

View File

@ -1035,6 +1035,87 @@ A.test(o2.__proto__) // true
上面示例中,对于修改原型链形成的继承,子类都取不到父类的私有属性,所以`in`运算符无效。
## 静态块
静态属性的一个问题是,它的初始化要么写在类的外部,要么写在`constructor()`方法里面。
```javascript
class C {
static x = 234;
static y;
static z;
}
try {
const obj = doSomethingWith(C.x);
C.y = obj.y
C.z = obj.z;
} catch {
C.y = ...;
C.z = ...;
}
```
上面示例中,静态属性`y``z`的值依赖静态属性`x`,它们的初始化写在类的外部(上例的`try...catch`代码块)。另一种方法是写到类的`constructor()`方法里面。这两种方法都不是很理想,前者是将类的内部逻辑写到了外部,后者则是每次新建实例都会运行一次。
为了解决这个问题ES2022 引入了[静态块](https://github.com/tc39/proposal-class-static-block)static block允许在类的内部设置一个代码块在类生成时运行一次主要作用是对静态属性进行初始化。
```javascript
class C {
static x = ...;
static y;
static z;
static {
try {
const obj = doSomethingWith(this.x);
this.y = obj.y;
this.z = obj.z;
}
catch {
this.y = ...;
this.z = ...;
}
}
}
```
上面代码中,类的内部有一个 static 代码块,这就是静态块。它的好处是将静态属性`y``z`的初始化逻辑,写入了类的内部,而且只运行一次。
每个类只能有一个静态块,在静态属性声明后运行。静态块的内部不能有`return`语句。
静态块内部可以使用类名或`this`,指代当前类。
```c
class C {
static x = 1;
static {
this.x; // 1
// 或者
C.x; // 1
}
}
```
上面示例中,`this.x``C.x`都能获取静态属性`x`
除了静态属性的初始化,静态块还有一个作用,就是将私有属性与类的外部代码分享。
```javascript
let getX;
export class C {
#x = 1;
static {
getX = obj => obj.#x;
}
}
console.log(getX(new C())); // 1
```
上面示例中,`#x`是类的私有属性,如果类外部的`getX()`方法希望获取这个属性,以前是要写在类的`constructor()`方法里面,这样的话,每次新建实例都会定义一次`getX()`方法。现在可以写在静态块里面,这样的话,只在类生成时定义一次。
## new.target 属性
`new`是从构造函数生成实例对象的命令。ES6 为`new`命令引入了一个`new.target`属性,该属性一般用在构造函数之中,返回`new`命令作用于的那个构造函数。如果构造函数不是通过`new`命令或`Reflect.construct()`调用的,`new.target`会返回`undefined`,因此这个属性可以用来确定构造函数是怎么调用的。