跳到主要内容

类的静态初始化块

· 阅读需 2 分钟
郭舒语 ([@_shu](https://twitter.com/_shu))

新的类静态初始化块语法允许开发者将针对某个类定义只运行一次的代码集中到一个地方。考虑下面的示例,其中一个伪随机数生成器使用静态块在 class MyPRNG 定义被评估时初始化一个熵池。

class MyPRNG {
constructor(seed) {
if (seed === undefined) {
if (MyPRNG.entropyPool.length === 0) {
throw new Error('熵池耗尽');
}
seed = MyPRNG.entropyPool.pop();
}
this.seed = seed;
}

getRandom() {}

static entropyPool = [];
static {
for (let i = 0; i < 512; i++) {
this.entropyPool.push(probeEntropySource());
}
}
}

作用域

每个静态初始化块都有其独立的 varlet/const 作用域。就像静态字段初始化器中一样,静态块中的 this 值是类构造函数本身。同样,静态块中的 super.property 指的是超类的静态属性。

var y = '外部 y';
class A {
static fieldA = 'A.fieldA';
}
class B extends A {
static fieldB = 'B.fieldB';
static {
let x = super.fieldA;
// → 'A.fieldA'
var y = this.fieldB;
// → 'B.fieldB'
}
}
// 由于静态块是其独立的 `var` 作用域,`var` 不会提升!
y;
// → '外部 y'

多个静态块

一个类可以有多个静态初始化块。这些块按文本顺序进行评估。此外,如果有任何静态字段,所有静态元素都会按文本顺序进行评估。

class C {
static field1 = console.log('字段 1');
static {
console.log('静态块 1');
}
static field2 = console.log('字段 2');
static {
console.log('静态块 2');
}
}
// → 字段 1
// 静态块 1
// 字段 2
// 静态块 2

访问私有字段

由于类静态初始化块始终嵌套在类内部,它可以访问该类的私有字段。

let getDPrivateField;
class D {
#privateField;
constructor(v) {
this.#privateField = v;
}
static {
getDPrivateField = (d) => d.#privateField;
}
}
getDPrivateField(new D('私有'));
// → 私有

就是这样了。祝你愉快使用面向对象!

类静态初始化块支持