Skip to content

JavaScript-Klassen verstehen - Wie funktioniert this in Klassen wirklich?

Published: at 06:00 AMSuggest Changes

this in Klassen: Struktur, Klarheit – und doch dynamisch

Mit der Einführung von Klassen in ES6 (ECMAScript 2015) hat JavaScript eine vertrautere Syntax für objektorientierte Programmierung erhalten. Viele Entwickler:innen hofften auf eine Vereinfachung der Arbeit mit this. Tatsächlich bringt die Klassen-Syntax mehr Struktur und Lesbarkeit. Doch unter der Haube bleibt JavaScript dynamisch. Auch in Klassen bleibt this kontextabhängig und kann verloren gehen, wenn man es falsch verwendet.

In diesem Artikel zeigen wir, wie this in Klassen wirklich funktioniert, worauf man achten muss, und wie man es effektiv binden kann, sowohl in Konstruktoren als auch mit modernen Features wie Public Class Fields oder Arrow Functions.

this im Konstruktor: Instanzen korrekt initialisieren

In JavaScript-Klassen referenziert this innerhalb des Konstruktors immer auf die aktuelle Instanz, die gerade erzeugt wird. Das ist der erwartete und konsistente Teil des Verhaltens.

class User {
  constructor(name) {
    this.name = name;
  }

  greet() {
    console.log(`Hallo, ich bin ${this.name}`);
  }
}

const user = new User("Emma");
user.greet(); // "Hallo, ich bin Emma"

Solange man Methoden über das Instanzobjekt (user.greet()) aufruft, funktioniert this wie erwartet.

Methoden verlieren this: Ein Klassiker

Was viele Entwickler:innen überrascht. Auch in Klassen verlieren Methoden ihren Kontext, wenn man sie aus dem Objekt herauslöst, etwa durch Weitergabe an Event-Handler oder als Callback.

const greetFn = user.greet;
greetFn(); // Fehler oder undefined – `this` zeigt nicht mehr auf `user`

Obwohl greet innerhalb einer Klasse definiert wurde, ist sie dennoch eine ganz normale Funktion. Und wie bei jeder Funktion in JavaScript gilt: Wird sie ohne Objektbezug aufgerufen, ist this entweder undefined (im Strict Mode) oder es wirft einen Fehler, da der Bezug zu this nicht mehr besteht (ohne Strict Mode).

Die Lösung: Binden im Konstruktor

Ein bewährtes Muster ist das explizite Binden der Methode an die Instanz innerhalb des Konstruktors. Das funktioniert mit der bind()-Methode.

class User {
  constructor(name) {
    this.name = name;
    this.greet = this.greet.bind(this);
  }

  greet() {
    console.log(`Hallo, ich bin ${this.name}`);
  }
}

const user = new User("Emma");
user.greet(); // "Hallo, ich bin Emma"

const greetFn = user.greet;
greetFn(); // "Hallo, ich bin Emma"

Jetzt zeigt this immer zuverlässig auf das aktuelle Objekt, auch wenn greet() außerhalb des Kontexts aufgerufen wird.

Alternativ: Arrow Functions als Klassenmethoden

Seit der Einführung von Public Class Fields kann man Methoden auch als Arrow Functions definieren. Da Arrow Functions kein eigenes this besitzen, übernehmen sie es vom umgebenden Scope, also von der Instanz.

class User {
  constructor(name) {
    this.name = name;
  }
  
  greet = () => {
    console.log(`Hallo, ich bin ${this.name}`);
  };
}

const user = new User("Emma");
user.greet(); // "Hallo, ich bin Emma"

const greetFn = user.greet;
greetFn(); // "Hallo, ich bin Emma"

Der Vorteil ist, dass hier kein manuelles Binden nötig ist. Der Nachteil liegt darin, dass diese Methode ist nicht auf dem Prototyp, sondern wird pro Instanz erzeugt sind, was zu höherem Speicherverbrauch führen kann.

this in Vererbungen und Superklassen

In vererbten Klassen bleibt das this-Verhalten konsistent. Innerhalb von Unterklassen verweist this ebenfalls auf die jeweilige Instanz, egal ob sie von der Basisklasse oder der abgeleiteten Klasse stammt.

class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(`${this.name} macht ein Geräusch`);
  }
}

class Dog extends Animal {
  speak() {
    console.log(`${this.name} bellt`);
  }
}

const dog = new Dog("Bello");
dog.speak(); // "Bello bellt"

Auch wenn speak() in Dog überschrieben wurde, bleibt this korrekt auf dog gesetzt. Das funktioniert selbst dann, wenn innerhalb der Methode super.speak() aufgerufen wird.

Klassen und Event-Handler: this richtig weitergeben

Ein häufiger Use-Case ist der Einsatz von Methoden als Event-Handler, etwa im DOM oder in UI-Frameworks. Hier ist besondere Vorsicht geboten, denn Event-Handler verlieren typischerweise ihren Bezug zu this.

class Button {
  constructor(label) {
    this.label = label;
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    console.log(`Button "${this.label}" wurde geklickt`);
  }
}

const b = new Button("Senden");
document.querySelector("button").addEventListener("click", b.handleClick);

Ohne das bind(this) im Konstruktor wäre this.label beim Klick undefined. Alternativ könnte allerdings auch hier eine Arrow Function genutzt werden, um den selben Effekt zu erzielen.

Fazit: Klassen bringen Klarheit – aber this bleibt dynamisch

JavaScript-Klassen sorgen für strukturierteren Code und helfen dabei, Objektorientierung übersichtlicher umzusetzen. Doch das Verhalten von this bleibt, wie auch im restlichen JavaScript, dynamisch und abhängig vom Aufrufkontext.

Wer Klassenmethoden außerhalb der Instanz aufruft, muss aktiv dafür sorgen, dass this korrekt gebunden bleibt, sei es über bind(), durch Arrow Functions oder moderne Class Fields. Ein klarer, bewusster Umgang mit this ist auch in Klassen entscheidend für stabilen, wartbaren Code.


Buy me a coffee

Wenn Dir meine Beiträge gefallen und sie Dir bei Deiner Arbeit helfen, würde ich mich über einen “Kaffee” und ein paar nette Worte von Dir freuen.

Buy me a coffee



Previous Post
Arrow Functions in JavaScript - Was this hier wirklich bedeutet
Next Post
JavaScript-Events und this - Was du über den Kontext in Event Handlern wissen musst