What is this inside an event handler?
By FrontendPro Editorial Team Updated 9/26/2026
Answer
It depends entirely on how you wrote the handler, and the two common styles give opposite answers.
A regular function added with addEventListener gets this set to the element the listener is attached to:
button.addEventListener("click", function () {
this.disabled = true; // `this` is the button
});
An arrow function has no this of its own, so it keeps whatever the surrounding scope had — usually the module or the class instance, not the element:
button.addEventListener("click", () => {
this.disabled = true; // `this` is NOT the button
});
Inside a class this trips people up
Passing a method directly detaches it from the instance:
class Form {
constructor(el) {
this.el = el;
el.addEventListener("submit", this.onSubmit); // broken
el.addEventListener("submit", this.onSubmit.bind(this)); // works
el.addEventListener("submit", (e) => this.onSubmit(e)); // also works
}
onSubmit(e) {
console.log(this.el); // undefined in the broken version
}
}
A class field is the tidiest fix, because the arrow is created per instance:
onSubmit = (e) => { console.log(this.el); };
Sidestep the question entirely
The event object already tells you which element you need, and it works the same in both styles:
event.currentTarget— the element the listener is on (whatthiswould have been).event.target— the deepest element actually clicked, which may be a child.
Preferring event.currentTarget makes handlers work regardless of how they were written, and it is the only reliable option inside arrow functions. One last trap: bind returns a new function, so keep a reference if you intend to call removeEventListener later.
