Start · Sprachen · JavaScript · Referenz · Statische Initialisierungsblöcke

Statische Initialisierungsblöcke

Keyword

Ein <code>static { … }</code>-Block im Klassenrumpf führt einmalig beim Auswerten der Klasse beliebige Anweisungen aus, um statische Eigenschaften zu initialisieren.

seit JavaScript ES2022 (Baseline: alle modernen Browser seit 2023, Kategorie: syntax

Signatur

class ClassName { static { /* Anweisungen */ } }

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

Typ
void
Beschreibung
Ein statischer Block ist kein Ausdruck und hat keinen 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);
{ theme: 'dunkel', lang: 'de' }

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));
Not Found Unbekannt

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));
Geheimcode 1234

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');
Feld a Block 1, a = 1 Feld b Block 2, b = 2 Klasse fertig

// Wichtig · Fallstricke

  • Kein return, kein await: Beides ist im statischen Block ein Syntaxfehler. arguments ist ebenfalls nicht erlaubt. Asynchrone Initialisierung muss man z. B. in einer statischen async-Methode oder einem gespeicherten Promise erledigen.
  • this ist die Klasse, nicht eine Instanz. In abgeleiteten Klassen ist super.eigenschaft erlaubt 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+.