Statische Initialisierungsblöcke
Baseline
2023
Newly available
Since March 2023, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.
Statische Initialisierungsblöcke werden innerhalb einer Klasse
deklariert. Sie enthalten Anweisungen, die während der Klasseninitialisierung ausgewertet werden. Dies ermöglicht flexiblere Initialisierungslogik als statische
Eigenschaften, wie z.B. die Verwendung von try...catch
oder das Setzen mehrerer Felder aus einem einzigen Wert. Die Initialisierung erfolgt im Kontext der aktuellen Klassendeklaration mit Zugriff auf privaten Zustand, was es der Klasse erlaubt, Informationen ihrer privaten Elemente mit anderen Klassen oder Funktionen zu teilen, die im selben Gültigkeitsbereich deklariert sind (analog zu "friend"-Klassen in C++).
Probieren Sie es aus
class ClassWithStaticInitializationBlock {
static staticProperty1 = "Property 1";
static staticProperty2;
static {
this.staticProperty2 = "Property 2";
}
}
console.log(ClassWithStaticInitializationBlock.staticProperty1);
// Expected output: "Property 1"
console.log(ClassWithStaticInitializationBlock.staticProperty2);
// Expected output: "Property 2"
Syntax
class ClassWithSIB {
static {
// …
}
}
Beschreibung
Ohne statische Initialisierungsblöcke könnte eine komplexe statische Initialisierung durch den Aufruf einer statischen Methode nach der Klassendeklaration erreicht werden:
class MyClass {
static init() {
// Access to private static fields is allowed here
}
}
MyClass.init();
Jedoch offenbart dieser Ansatz ein Implementierungsdetail (die init()
-Methode) dem Nutzer der Klasse. Andererseits hat jede außerhalb der Klasse deklarierte Initialisierungslogik keinen Zugriff auf private statische Felder. Statische Initialisierungsblöcke erlauben es, beliebige Initialisierungslogik innerhalb der Klasse zu deklarieren und auszuführen, während die Klasse ausgewertet wird.
Eine Klasse
kann beliebig viele static {}
-Initialisierungsblöcke in ihrem Klassenkörper haben.
Diese werden zusammen mit allen dazwischenliegenden statischen Feldinitialisierern in der Reihenfolge ausgewertet, in der sie deklariert sind.
Jede statische Initialisierung einer Superklasse wird zuerst durchgeführt, vor der ihrer Unterklassen.
Der Gültigkeitsbereich der innerhalb des statischen Blocks deklarierten Variablen ist lokal für den Block. Dies schließt var
, function
, const
und let
Deklarationen ein. var
Deklarationen werden nicht aus dem statischen Block herausgehoben.
var y = "Outer y";
class A {
static field = "Inner y";
static {
// var y only hoisted inside block
console.log(y); // undefined <-- not 'Outer y'
var y = this.field;
}
}
// var y defined in static block is not hoisted
// outside the block
console.log(y); // 'Outer y'
Das this
innerhalb eines statischen Blocks bezieht sich auf das Konstruktorobjekt der Klasse.
super.property
kann verwendet werden, um auf statische Eigenschaften der Superklasse zuzugreifen.
Es ist jedoch ein Syntaxfehler, super()
in einem statischen Initialisierungsblock einer Klasse zu rufen oder das arguments
-Objekt zu verwenden.
Die Anweisungen werden synchron ausgewertet. Sie können await
oder yield
in diesem Block nicht verwenden. (Stellen Sie sich die Initialisierungsanweisungen als implizit in eine Funktion eingerahmt vor.)
Der Gültigkeitsbereich des statischen Blocks ist innerhalb des lexikalischen Gültigkeitsbereichs des Klassenkörpers verschachtelt und kann auf private Namen zugreifen, die innerhalb der Klasse deklariert sind, ohne dass ein Syntaxfehler entsteht.
Statische Felder-Initialisierer und statische Initialisierungsblöcke werden nacheinander ausgewertet. Der Initialisierungsblock kann auf Feldwerte über ihm, aber nicht unter ihm verweisen. Alle statischen Methoden werden vorher hinzugefügt und können aufgerufen werden, obwohl ihr Verhalten möglicherweise nicht wie erwartet ist, wenn sie auf Felder unterhalb des aktuellen Blocks verweisen.
Hinweis:
Dies ist wichtiger bei privaten statischen Feldern, da der Zugriff auf ein nicht initialisiertes privates Feld einen TypeError
verursacht, selbst wenn das private Feld darunter deklariert ist. (Wird das private Feld nicht deklariert, wäre es ein früher SyntaxError
.)
Ein statischer Initialisierungsblock darf keine Dekoratoren haben (die Klasse selbst darf).
Beispiele
>Mehrere Blöcke
Der folgende Code demonstriert eine Klasse mit statischen Initialisierungsblöcken und dazwischenliegenden statischen Feldinitialisierern. Die Ausgabe zeigt, dass die Blöcke und Felder in Ausführungsreihenfolge ausgewertet werden.
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'
Beachten Sie, dass jede statische Initialisierung einer Superklasse zuerst durchgeführt wird, bevor die ihrer Unterklassen erfolgt.
Verwendung von this und super
Das this
innerhalb eines statischen Blocks bezieht sich auf das Konstruktorobjekt der Klasse.
Dieser Code zeigt, wie auf ein öffentliches statisches Feld zugegriffen werden kann.
class A {
static field = "static field";
static {
console.log(this.field);
}
}
// 'static field'
Die super.property
-Syntax kann innerhalb eines static
-Blocks verwendet werden, um auf statische Eigenschaften einer Superklasse zu verweisen.
class A {
static field = "static field";
}
class B extends A {
static {
console.log(super.field);
}
}
// 'static field'
Zugang zu privaten Elementen
Das untenstehende Beispiel zeigt, wie der Zugriff auf ein privates Instanzfeld einer Klasse aus einem Objekt außerhalb der Klasse gewährt werden kann (Beispiel vom 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'
Spezifikationen
Specification |
---|
ECMAScript® 2026 Language Specification> # prod-ClassStaticBlock> |
Browser-Kompatibilität
Loading…
Siehe auch
- Verwendung von Klassen Leitfaden
- Klassen
static
class
- Klassenstatische Initialisierungsblöcke auf v8.dev (2021)
- ES2022 Feature: Klassenstatische Initialisierungsblöcke von Dr. Axel Rauschmayer (2021)