Signatur
Beschreibung
Statische Initialisierungsblöcke (static { … }) sind Codeblöcke innerhalb einer Klassendefinition. Sie laufen genau einmal, und zwar wenn die Klasse selbst ausgewertet wird, nicht bei jedem new. Innerhalb des Blocks zeigt this auf den Klassenkonstruktor. Damit lassen sich statische Felder mit Logik befüllen, die über einen einfachen Ausdruck hinausgeht, z. B. mit Schleifen, try...catch oder mehreren Zwischenschritten.
Ein großer Vorteil: Der Block gehört zum Gültigkeitsbereich der Klasse und hat deshalb Zugriff auf private Member (#feld). So kann man privaten Zustand gezielt mit Code außerhalb der Klasse teilen, etwa indem man eine Zugriffsfunktion an eine äußere Variable zuweist. Das ersetzt das früher übliche Muster, statische Initialisierung erst nach der Klassendefinition zu erledigen.
Eine Klasse darf mehrere statische Blöcke enthalten. Sie werden zusammen mit den statischen Feld-Initialisierern in der Reihenfolge ausgeführt, in der sie im Quelltext stehen. Variablen, die mit var, let oder const im Block deklariert werden, sind lokal und nach außen nicht sichtbar.
Rückgabewert
return ist darin ein Syntaxfehler.Beispiele
Komplexe statische Initialisierung mit Fehlerbehandlung
class Config {
static defaults = { theme: 'hell', lang: 'de' };
static settings;
static {
try {
const raw = '{"theme":"dunkel"}'; // z. B. aus einer Umgebungsvariable
this.settings = { ...this.defaults, ...JSON.parse(raw) };
} catch {
this.settings = { ...this.defaults };
}
}
}
console.log(Config.settings);
Nachschlagetabelle per Schleife aufbauen
class HttpStatus {
static byCode = new Map();
static {
const entries = [[200, 'OK'], [404, 'Not Found'], [500, 'Internal Server Error']];
for (const [code, text] of entries) {
this.byCode.set(code, text);
}
}
static text(code) {
return HttpStatus.byCode.get(code) ?? 'Unbekannt';
}
}
console.log(HttpStatus.text(404));
console.log(HttpStatus.text(418));
Privaten Zustand mit Code außerhalb teilen
let readSecret;
class Tresor {
#inhalt;
constructor(inhalt) {
this.#inhalt = inhalt;
}
static {
// Der Block hat Zugriff auf #inhalt
readSecret = (tresor) => tresor.#inhalt;
}
}
const t = new Tresor('Geheimcode 1234');
console.log(readSecret(t));
Ausführungsreihenfolge von Feldern und Blöcken
class Reihenfolge {
static a = (console.log('Feld a'), 1);
static { console.log('Block 1, a =', this.a); }
static b = (console.log('Feld b'), 2);
static { console.log('Block 2, b =', this.b); }
}
console.log('Klasse fertig');
// Wichtig · Fallstricke
- Kein
return, keinawait: Beides ist im statischen Block ein Syntaxfehler.argumentsist ebenfalls nicht erlaubt. Asynchrone Initialisierung muss man z. B. in einer statischenasync-Methode oder einem gespeicherten Promise erledigen. thisist die Klasse, nicht eine Instanz. In abgeleiteten Klassen istsuper.eigenschafterlaubt und greift auf statische Member der Elternklasse zu.super()ist dagegen nicht erlaubt.- Reihenfolge beachten: Ein Block sieht nur statische Felder, die im Quelltext vor ihm stehen. Spätere Felder sind zu diesem Zeitpunkt noch
undefined. - Der Block läuft einmal pro Klassenauswertung. Werden Klassen dynamisch in einer Funktion erzeugt, läuft er bei jedem Aufruf erneut.
- Ausnahmen, die im Block nicht abgefangen werden, brechen die Klassendefinition ab. Die Klasse ist danach nicht nutzbar.
- Kompatibilität: Chrome 94+, Firefox 93+, Safari 16.4+, Node.js 16.11+. Für ältere Umgebungen transpilieren, z. B. mit Babel (
@babel/plugin-transform-class-static-block) oder TypeScript 4.4+.