Start · Sprachen · JavaScript · Referenz · constructor

constructor

Keyword

Die <code>constructor</code>-Methode ist eine spezielle Methode einer Klasse, die beim Aufruf mit <code>new</code> eine neue Instanz erzeugt und initialisiert.

seit JavaScript ES2015 Kategorie: syntax

Signatur

constructor(...args) { /* … */ }

Beschreibung

Die Methode constructor wird automatisch ausgeführt, wenn eine Klasse mit new instanziiert wird. Hier legt man den Anfangszustand des Objekts fest: Eigenschaften auf this zuweisen, Argumente prüfen, Standardwerte setzen oder Ressourcen vorbereiten. Pro Klasse darf es höchstens einen constructor geben, sonst wirft der Parser einen SyntaxError.

Gibt man keinen Konstruktor an, erzeugt JavaScript einen Standardkonstruktor. Bei einer Basisklasse ist das constructor() {}, bei einer abgeleiteten Klasse constructor(...args) { super(...args); }. Die Argumente werden also automatisch an die Elternklasse weitergereicht.

In abgeleiteten Klassen (class B extends A) muss super(...) aufgerufen werden, bevor man auf this zugreift. Erst dieser Aufruf erzeugt und initialisiert die Instanz über den Elternkonstruktor. Klassenfelder (field = wert) der abgeleiteten Klasse werden direkt nach dem Rücklauf von super() initialisiert. Bei Basisklassen geschieht das vor dem ersten Befehl im Konstruktor.

Normalerweise gibt ein Konstruktor nichts zurück, dann ist das Ergebnis von new die Instanz this. Gibt er ausdrücklich ein Objekt zurück, ersetzt dieses die Instanz. Primitive Rückgabewerte werden in Basisklassen ignoriert. In abgeleiteten Klassen führen sie (außer undefined) zu einem TypeError.

Parameter

Name Typ Default Beschreibung
$...args any Beliebige Parameter, die beim Aufruf new Klasse(...args) übergeben werden. Standardwerte, Destrukturierung und Restparameter sind erlaubt.

Rückgabewert

Typ
void | object
Beschreibung
In der Regel kein Rückgabewert: new liefert dann die neue Instanz. Gibt der Konstruktor ausdrücklich ein Objekt zurück, liefert new dieses Objekt statt der Instanz.

Beispiele

Einfache Klasse mit Validierung im Konstruktor

class Benutzer {
  constructor(name, email, rolle = 'gast') {
    if (!email.includes('@')) {
      throw new TypeError(`Ungültige E-Mail: ${email}`);
    }
    this.name = name;
    this.email = email;
    this.rolle = rolle;
    this.erstelltAm = new Date();
  }

  toString() {
    return `${this.name} <${this.email}> (${this.rolle})`;
  }
}

const anna = new Benutzer('Anna', 'anna@example.com', 'admin');
console.log(String(anna));

try {
  new Benutzer('Bob', 'kein-mail');
} catch (err) {
  console.log(err.message);
}
Anna <anna@example.com> (admin) Ungültige E-Mail: kein-mail

Vererbung: super() vor this aufrufen

class HttpFehler extends Error {
  constructor(status, nachricht, options) {
    super(nachricht, options); // muss vor jedem Zugriff auf this stehen
    this.name = 'HttpFehler';
    this.status = status;
  }
}

class NichtGefunden extends HttpFehler {
  constructor(url) {
    super(404, `Ressource nicht gefunden: ${url}`);
    this.url = url;
  }
}

const fehler = new NichtGefunden('/api/users/42');
console.log(fehler instanceof HttpFehler, fehler.status, fehler.message);
true 404 Ressource nicht gefunden: /api/users/42

Options-Objekt mit Destrukturierung und privaten Feldern

class ApiClient {
  #token;

  constructor({ baseUrl, token, timeout = 5000 } = {}) {
    if (!baseUrl) throw new Error('baseUrl ist erforderlich');
    this.baseUrl = baseUrl.replace(/\/$/, '');
    this.timeout = timeout;
    this.#token = token;
  }

  async get(pfad) {
    const res = await fetch(`${this.baseUrl}${pfad}`, {
      headers: { Authorization: `Bearer ${this.#token}` },
      signal: AbortSignal.timeout(this.timeout)
    });
    return res.json();
  }
}

const client = new ApiClient({ baseUrl: 'https://api.example.com/', token: 'abc' });
console.log(client.baseUrl, client.timeout);
https://api.example.com 5000

Singleton durch Rückgabe eines Objekts

class Konfiguration {
  static #instanz;

  constructor() {
    if (Konfiguration.#instanz) {
      return Konfiguration.#instanz; // ersetzt die neue Instanz
    }
    this.werte = new Map();
    Konfiguration.#instanz = this;
  }
}

const a = new Konfiguration();
const b = new Konfiguration();
console.log(a === b);
true

// Wichtig · Fallstricke

  • Zugriff auf this vor super() in abgeleiteten Klassen wirft einen ReferenceError. Fehlt der Aufruf von super() ganz und wird kein Objekt zurückgegeben, gibt es ebenfalls einen ReferenceError.
  • Klassen lassen sich nur mit new aufrufen. Klasse() ohne new wirft einen TypeError.
  • Der constructor darf kein Getter, Setter, Generator oder async sein (SyntaxError). Für asynchrone Initialisierung eignet sich eine statische Fabrikmethode, z. B. static async create().
  • Methoden werden im Konstruktor nicht automatisch an die Instanz gebunden. Wer Methoden als Callback übergibt (z. B. an Event-Listener), bindet sie mit this.handle = this.handle.bind(this) oder verwendet Pfeilfunktionen als Klassenfelder.
  • Eine Überladung wie in Java oder C# gibt es nicht. Varianten bildet man mit Standardwerten, Options-Objekten oder statischen Fabrikmethoden.
  • Die gleichnamige Eigenschaft Object.prototype.constructor (z. B. obj.constructor === Klasse) ist ein anderes Konzept: Sie verweist auf die Funktion, die die Instanz erzeugt hat.
  • Nur ein Konstruktor mit dem Namen constructor als einfacher Bezeichner ist speziell. ["constructor"]() als berechneter Name definiert eine gewöhnliche Methode.