Menu

this in JavaScript verstehen: Bindungsregeln & Fallstricke

Wie this in JavaScript wirklich funktioniert – die vier Bindungsregeln, warum Arrow Functions eine Ausnahme sind und wie du den Klassiker 'this is undefined' sicher umgehst.

this wird zur Aufrufzeit festgelegt

Die meisten Missverständnisse rund um this in JavaScript entstehen aus einer einzigen falschen Annahme: dass this davon abhängt, wo eine Funktion definiert wurde. Tut es aber nicht. this hängt davon ab, wie die Funktion aufgerufen wird.

Schau dir dieselbe Funktion zweimal aufgerufen an:

index.js
Output
Click Run to see the output here.

Dieselbe Funktion, unterschiedliches this. Beim ersten Aufruf steht user vor dem Punkt – also ist this gleich user. Beim zweiten Aufruf steht nichts davor, und damit ist this eben undefined. An der Funktion selbst hat sich nichts geändert, nur an der Aufrufstelle.

Merk dir diesen Gedanken: Um herauszufinden, was this ist, schau dir den Aufruf an, nicht die Definition.

Die vier Bindungsregeln für this

Es gibt vier Arten, wie this gesetzt wird. So gut wie jede Frage, die du jemals zu this haben wirst, lässt sich beantworten, indem du herausfindest, welche dieser Regeln gerade greift.

1. Methodenaufruf: obj.fn()

Wird eine Funktion als Eigenschaft eines Objekts aufgerufen, ist this genau dieses Objekt:

index.js
Output
Click Run to see the output here.

Was links vom Punkt steht, wird zu this. So simpel ist die Regel.

2. Direkter Aufruf: fn()

Wenn du eine Funktion ohne vorangestelltes Objekt aufrufst, ist this im Strict Mode (den Module und Klassen automatisch aktivieren) undefined – im Sloppy Mode dagegen das globale Objekt:

index.js
Output
Click Run to see the output here.

Genau hier kommen die berüchtigten „this is undefined"-Fehler her. Sobald du eine Methode von ihrem Objekt löst, wird aus dem Methodenaufruf ein ganz normaler Funktionsaufruf:

index.js
Output
Click Run to see the output here.

Kein counter. vor dem Aufruf, also auch keine Bindung. Die Funktion erinnert sich einfach nicht mehr an das Objekt, aus dem sie stammt.

3. Explizites Binding: .call(), .apply(), .bind()

Mit diesen Methoden kannst du this gezielt auf einen beliebigen Wert setzen:

index.js
Output
Click Run to see the output here.

.call und .apply rufen die Funktion sofort auf; der Unterschied liegt nur darin, wie die Argumente übergeben werden. .bind hingegen liefert eine neue Funktion zurück, bei der this dauerhaft festgezurrt ist – praktisch für Callbacks.

4. Aufruf mit new: new Fn()

Wird eine Funktion mit new aufgerufen, entsteht ein frisches Objekt, das an this gebunden wird:

index.js
Output
Click Run to see the output here.

Klassen nutzen diesen Mechanismus intern. Wir schauen sie uns in einem späteren Kapitel an.

Arrow Functions haben kein eigenes this

Arrow Functions halten sich bewusst nicht an die oben genannten Regeln. Sie binden this überhaupt nicht – stattdessen übernehmen sie es aus dem umgebenden Scope, und zwar fest eingefroren zu dem Zeitpunkt, an dem die Arrow Function definiert wird:

index.js
Output
Click Run to see the output here.

Die Arrow-Function auf Modul-Ebene fängt das this des Moduls ein – und das ist undefined. Auch wenn du sie als user.arrow() aufrufst: Die Arrow Function weigert sich schlicht, sich neu zu binden.

Klingt nach einem Bug, ist aber genau der Sinn der Sache. Arrow Functions spielen ihre Stärke nämlich innerhalb von Methoden aus, wenn du das äußere this beibehalten willst:

index.js
Output
Click Run to see the output here.

Die Pfeilfunktion innerhalb von setInterval erbt ihr this von start, und start wurde als timer.start() aufgerufen. Deshalb funktioniert this.seconds wie erwartet. Eine klassische function an derselben Stelle hätte ihr eigenes this bekommen (das, was setInterval übergibt) – und alles wäre kaputt.

Faustregel: Pfeilfunktionen für Callbacks innerhalb von Methoden, normale Funktionen für die Methoden selbst.

Die klassische Callback-Falle

So geht this in JavaScript am häufigsten verloren: Du übergibst eine Methode als Callback, und schon ist das this-Binding weg:

index.js
Output
Click Run to see the output here.

setTimeout ruft die Funktion als normalen Funktionsaufruf auf, nicht als c.increment(). Es gibt drei Wege, das zu beheben:

index.js
Output
Click Run to see the output here.

Alle drei Varianten funktionieren. Am klarsten ist meistens die Arrow-Wrapper-Variante.

this auf oberster Ebene

Was this auf oberster Ebene bedeutet, hängt davon ab, wo dein Code läuft:

  • Browser-Skript (kein Modul): this ist window.
  • ES-Modul (also auch der meiste moderne, gebundelte Code): this ist undefined.
  • Node.js-CommonJS-Modul: this entspricht module.exports.

Wenn du umgebungsunabhängig zuverlässig auf das globale Objekt zugreifen willst, nimm globalThis:

index.js
Output
Click Run to see the output here.

Im Alltag solltest du dich nicht auf this auf Top-Level verlassen. Wenn du tatsächlich das globale Objekt brauchst, greif zu globalThis – ansonsten reich die Werte lieber explizit weiter.

Ein kurzer Entscheidungsbaum

Wenn du irgendwo this siehst und nicht genau weißt, worauf es zeigt, arbeite dich durch diese Liste:

  1. Ist die Funktion eine Arrow Function? Dann ist this genau das, was im umgebenden Scope galt. Der Aufrufort spielt keine Rolle.
  2. Wurde sie mit new aufgerufen? Dann ist this das neu erzeugte Objekt.
  3. Wurde sie über .call, .apply oder als gebundene Funktion aufgerufen? Dann ist this der übergebene Wert.
  4. Wurde sie als obj.method() aufgerufen? Dann ist this gleich obj.
  5. Wurde sie als einfaches fn() aufgerufen? Dann ist this im Strict Mode undefined.

Diese Reihenfolge – genau in dieser Abfolge – klärt jeden Fall.

Als Nächstes: Higher-Order Functions

Jetzt, wo this kein Rätsel mehr ist, bist du bereit für das Pattern, das JavaScript so ausdrucksstark macht: Funktionen als Werte herumzureichen. Im nächsten Kapitel schauen wir uns Higher-Order Functions an – also Funktionen, die andere Funktionen annehmen oder zurückgeben – und wie sie Array-Methoden, Event-Handler und den Großteil von echtem JavaScript-Code erst möglich machen.

Häufig gestellte Fragen

Worauf verweist this in JavaScript eigentlich?

this verweist auf das Objekt, auf dem eine Funktion aufgerufen wird – nicht darauf, wo die Funktion definiert wurde. Bei user.greet() ist this also user. Rufst du dagegen einfach greet() auf, ist this im strict mode undefined (bzw. das globale Objekt im sloppy mode). Entscheidend ist immer der Aufrufort, nicht der Definitionsort.

Warum ist this innerhalb meiner Funktion undefined?

Sehr wahrscheinlich hast du eine Methode vom Objekt 'abgelöst' und separat aufgerufen – oder sie als Callback übergeben. const fn = user.greet; fn(); verliert die Bindung, weil am Aufrufort nichts mehr links vom Punkt steht. Lösung: .bind(user), ein Wrapper mit Arrow Function, oder direkt user.greet() aufrufen.

Was ist bei this in Arrow Functions anders?

Arrow Functions haben kein eigenes this. Sie übernehmen es aus dem umgebenden Scope zum Zeitpunkt der Definition. Genau deshalb sind sie perfekt für Callbacks innerhalb von Methoden, wenn du das äußere this behalten willst. Im Gegenzug kannst du this bei einer Arrow Function weder mit .call(), .apply() noch .bind() ändern.

Was ist this auf der obersten Ebene eines Scripts?

In einem klassischen Script im Browser ist this auf Top-Level das window-Objekt. In einem ES-Modul ist es undefined. In CommonJS-Modulen unter Node.js zeigt es auf module.exports. Die umgebungsübergreifende Referenz heißt globalThis – die zeigt immer auf das globale Objekt.

Lerne mit Coddy zu programmieren

LOS GEHT'S