类静态初始化块

发布日期 · 标签:ECMAScript

新的类静态初始化块语法允许开发者将应该为给定类定义运行一次的代码收集起来,并放在一个地方。考虑以下示例,其中一个伪随机数生成器使用静态块来初始化熵池一次,当 class MyPRNG 定义被评估时。

class MyPRNG {
constructor(seed) {
if (seed === undefined) {
if (MyPRNG.entropyPool.length === 0) {
throw new Error('Entropy pool exhausted');
}
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 = 'outer 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'
}
}
// Since static blocks are their own `var` scope, `var`s do not hoist!
y;
// → 'outer y'

多个块 #

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

class C {
static field1 = console.log('field 1');
static {
console.log('static block 1');
}
static field2 = console.log('field 2');
static {
console.log('static block 2');
}
}
// → field 1
// static block 1
// field 2
// static block 2

访问私有字段 #

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

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

就是这样。祝您面向对象编程愉快!

类静态初始化块支持 #