新しいクラスの静的初期化ブロック構文を使用すると、デベロッパーは特定のクラス定義に対して 1 回実行する必要があるコードを収集し、それらを 1 つの場所に配置できます。次の例では、疑似乱数ジェネレータが静的ブロックを使用して、class MyPRNG 定義が評価されたときにエントロピープールを 1 回初期化します。
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());
    }
  }
}スコープ #
静的初期化ブロックはそれぞれ独自の var および let/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'複数のブロック #
1 つのクラスで複数の静的初期化ブロックを使用できます。これらのブロックは、テキスト順に評価されます。さらに、静的フィールドがある場合、すべての静的要素がテキスト順に評価されます。
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以上です。オブジェクト指向プログラミングを楽しみましょう!
クラスの静的初期化ブロックのサポート #
- Chrome: バージョン 91 以降でサポート
- Firefox: 未サポート
- Safari: 未サポート
- Node.js: 未サポート
- Babel: サポート