このページはコミュニティーの尽力で英語から翻訳されました。MDN Web Docsコミュニティーについてもっと知り、仲間になるにはこちらから。
静的初期化ブロック
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since 2023年3月.
静的初期化ブロックはクラス内で宣言されます。これは、クラスの初期化の時に評価される文を格納します。これにより、静的プロパティよりも柔軟な初期化ロジックが可能になり、try...catch を使用したり、 1 つの値から複数のフィールドを設定したりすることができます。初期化は現在のクラス宣言のコンテキストで実行され、プライベート要素にアクセスすることができます。つまり、インスタンスのプライベートフィールドを持つクラスと、同じスコープで宣言された他のクラスや関数との間で情報を共有するためにも使用できます(C++ の "friend" クラスに似ています)。
In this article
試してみましょう
class ClassWithStaticInitializationBlock { static staticProperty1 = "Property 1"; static staticProperty2; static { this.staticProperty2 = "Property 2"; }}console.log(ClassWithStaticInitializationBlock.staticProperty1);// 予想される結果: "Property 1"console.log(ClassWithStaticInitializationBlock.staticProperty2);// 予想される結果: "Property 2"構文
class ClassWithSIB { static { // … }}解説
静的初期化ブロックを使わない場合、クラス宣言の後で静的メソッドを呼び出すことで、複雑な静的初期化を行うことができます。
class MyClass { static init() { // プライベート静的フィールドにアクセスすることができる }}MyClass.init();しかし、この手法では実装の詳細(init() メソッド)がクラスのユーザーに公開されてしまいます。一方、クラスの外部で宣言された初期化ロジックはプライベート静的フィールドにアクセスすることはできません。静的初期化ブロックでは、任意の初期化ロジックをクラス内で宣言し、クラスの評価中に実行することができます。
class は、そのクラス本体に任意の数のstatic {} 初期化ブロックを置くことができます。これらのブロックは、宣言された順に、静的フィールド初期化子とともに評価されます。スーパークラスの静的初期化は、そのサブクラスの初期化よりも先に実行されます。
静的ブロックの内部で宣言された変数のスコープは、そのブロックのローカルなものです。ここには初期化ブロック内で宣言されたvar,function,const,let は、そのブロックのローカル変数であるため、var 宣言は静的ブロックの外に巻き上げされることはありません。
var y = "Outer y";class A { static field = "Inner y"; static { // var y はブロックの中にしか巻き上げられない console.log(y); // undefined <-- not 'Outer y' var y = this.field; }}// 静的ブロックで定義された var y は// ブロックの外に巻き上げられないconsole.log(y); // 'Outer y'静的ブロック内のthis は、そのクラスのコンストラクター オブジェクトを参照します。super.プロパティ を使用して、スーパークラスの静的プロパティにアクセスすることができます。ただし、クラスの静的初期化ブロック内でsuper() を呼び出したり、arguments オブジェクトを使用したりするのは構文エラーであることに注意してください。
式は同期的に評価されます。初期化子式で(await やyield)を使用することはできません。(初期化子式は暗黙に関数に包まれていると考えてください)。
静的ブロックのスコープは、クラス本体の字句スコープの中で入れ子になり、構文エラーを発生させることなく、クラス内で宣言されたプライベート名にアクセスすることができます。
静的フィールド初期化子と静的初期化ブロックは、 1 つずつ評価されます。フィールド初期化子は、それより上のフィールド値を参照することはできますが、それより下のフィールド値を参照することはできません。静的メソッドはすべて事前に追加され、アクセスすることができますが、初期化されるフィールドより下のフィールドを参照している場合、呼び出すと期待した動作をしないことがあります。
メモ:これはプライベート静的フィールドではより重要です。初期化されていないプライベートフィールドにアクセスすると、たとえそのプライベートフィールドが下で宣言されていたとしても、TypeError が発生するからです。(プライベートフィールドが宣言されていない場合は、早期にSyntaxError となります。)
静的初期化ブロックはデコレーターを持つことができません(クラス自身は持つことができます)。
例
>複数のブロック
下記コードは、静的初期化ブロックと静的フィールド初期化子を挟み込んだクラスを示すものです。出力は、ブロックとフィールドが実行順に評価されることを示しています。
class MyClass { static field1 = console.log("static field1"); static { console.log("static block1"); } static field2 = console.log("static field2"); static { console.log("static block2"); }}// 'static field1'// 'static block1'// 'static field2'// 'static block2'スーパークラスの静的な初期化は、サブクラスの初期化よりも最初に行われることに注意してください。
this と super の使用
静的ブロック内のthis は、そのクラスのコンストラクター オブジェクトを参照します。このコードは、パブリック静的フィールドにアクセスする方法を示しています。
class A { static field = "static field"; static { console.log(this.field); }}// 'static field'super.property 構文をstatic ブロックの中で使用すると、スーパークラスの静的プロパティを参照することができます。
class A { static field = "static field";}class B extends A { static { console.log(super.field); }}// 'static field'プライベート要素へのアクセス
下記は、クラス外のオブジェクトからクラスのプライベートインスタンスフィールドにアクセスを許可する例です(v8.dev blogより)。
let getDPrivateField;class D { #privateField; constructor(v) { this.#privateField = v; } static { getDPrivateField = (d) => d.#privateField; }}console.log(getDPrivateField(new D("private"))); // 'private'仕様書
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # prod-ClassStaticBlock> |
ブラウザーの互換性
関連情報
- クラスの使用ガイド
- クラス
staticclass- Class static initialization blocks (v8.dev blog)
- ES2022 feature: class static initialization blocks (Dr. Axel Rauschmayer, 2021)