this
in Event Handlern: Wenn der Klick mehr auslöst als erwartet
Event Handler gehören zu den Grundlagen der JavaScript-Entwicklung, ob bei DOM-Elementen im Browser oder Komponenten in Frameworks. Doch sobald man sich mit dem Schlüsselwort this
in einem Event-Handler beschäftigt, taucht häufig Unsicherheit auf. Warum zeigt this
manchmal auf das DOM-Element, manchmal auf undefined
und manchmal gar nicht auf das, was man erwartet?
In diesem Beitrag sehen wir uns das Verhalten von this
in verschiedenen Typen von Event Handlern an, mit einem Fokus auf “normale” Funktionen, Arrow Functions, Klassenmethoden und der manuellen Kontextbindung.
Das Standardverhalten: this
zeigt auf das Element
In klassischen DOM-Event-Handlern, die mit einer normalen Funktion definiert wurden, zeigt this
beim Auslösen des Events standardmäßig auf das Element, das das Event ausgelöst hat.
const button = document.querySelector("button");
button.addEventListener("click", function () {
console.log(this); // <button>...</button>
});
Dieses Verhalten ist oft gewünscht. Zum Beispiel, wenn man über this
das aktuelle Element manipulieren will.
button.addEventListener("click", function () {
this.textContent = "Geklickt!";
});
Hier ist this
das Button-Element selbst.
Arrow Functions: this
bleibt lexikalisch
Wenn der Event-Handler jedoch als Arrow Function definiert ist, übernimmt this
nicht das Element, sondern das this
aus dem umgebenden Kontext, also z. B. window
im globalen Scope oder die umgebende Klasse in einem OOP-Szenario.
button.addEventListener("click", () => {
console.log(this); // window oder umgebender Kontext
});
Dieses Verhalten ist besonders nützlich in Klassen oder Closures, wo man auf ein externes this
zugreifen möchte, etwa auf eine bestimmte Komponente, nicht das DOM-Element. In anderen Szenarien kann dieses Verhalten allerdings auch zu ungewünschten Effekten führen.
Typisches Szenario: Event Handler in Klassen
In modernen Anwendungen arbeitet man oft mit Klassen, z. B. in Vanilla-JavaScript-Komponenten oder in Frameworks wie React (mit Klassenkomponenten). Hier wird häufig erwartet, dass this
auf die jeweilige Instanz zeigt, aber das klappt nicht automatisch.
class MyButton {
constructor(label) {
this.label = label;
const btn = document.querySelector("button");
btn.addEventListener("click", this.handleClick);
}
handleClick() {
console.log(`Geklickt: ${this.label}`);
}
}
new MyButton("Senden"); // "TypeError: Cannot read properties of null (reading 'addEventListener')
Warum? Weil this.handleClick
ohne Bindung übergeben wurde, this
zeigt im Event nicht auf die Instanz der Klasse, sondern auf das Element aus dem es aufgerufen wurde, oder ist undefined
im Strict Mode.
Die Lösung: bind()
oder Arrow Functions
1. Binden der Methode im Konstruktor
class MyButton {
constructor(label) {
this.label = label;
this.handleClick = this.handleClick.bind(this);
document.querySelector("button").addEventListener("click", this.handleClick);
}
handleClick() {
console.log(`Geklickt: ${this.label}`);
}
}
Jetzt ist this
immer korrekt auf die Instanz der Klasse gebunden und das unabhängig davon, wie der Event-Handler aufgerufen wird.
2. Arrow Function als Methode
class MyButton {
constructor(label) {
this.label = label;
document.querySelector("button").addEventListener("click", this.handleClick);
}
handleClick = () => {
console.log(`Geklickt: ${this.label}`);
};
}
Da Arrow Functions kein eigenes this
besitzen, übernehmen sie das this
der Klasse, zuverlässig und leserlich.
Inline-Handler: this
im HTML-Attribut
Auch wenn es heute nicht mehr best practice ist, können Event-Handler auch direkt im HTML gesetzt werden:
<button onclick="alert(this.textContent)">Klick mich!</button>
Hier verweist this
auf das Element selbst, aber solche Konstrukte sind schwer wartbar und sollten in modernen Projekten vermieden werden.
this
und Event Delegation
Beim Delegieren von Events über übergeordnete Elemente (z. B. document
oder ul
) zeigt this
nicht auf das ursprüngliche Ziel (event.target
), sondern auf das Element, an das der Handler gebunden wurde:
document.querySelector("ul").addEventListener("click", function (event) {
console.log(this); // <ul>...</ul>
console.log(event.target); // Das tatsächlich geklickte <li>
});
Das ist gewollt und macht this
bei Event Delegation nützlich für das übergeordnete Element, während event.target
den eigentlichen Auslöser liefert.
Fazit: this
in Event Handlern – stabil, aber kontextabhängig
Je nachdem, wie ein Event Handler definiert ist, ob als normale Funktion, Arrow Function oder Klassenmethode, verändert sich das Verhalten von this
. Es zeigt entweder auf das auslösende DOM-Element, auf eine Klasseninstanz oder auf den globalen Kontext. Dieses Verhalten ist mächtig, kann aber zu Verwirrung führen, wenn man die Unterschiede nicht kennt.
Wer Event Handler sauber und sicher schreiben will, sollte die Bindung von this
aktiv steuern, entweder mit bind()
, mit Arrow Functions oder über moderne Klassenfeatures. Dann bleibt der Kontext immer nachvollziehbar, auch bei komplexerem 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.