In JavaScript, for an event handler that needs access to private members and functions, I can rely on the function scope of those to be accessible within my event handler function, and do something like this:
theElement.addEventListener("click", onClick);
and later:
theElement.removeEventListener("click", onClick);
In TypeScript, I need to use an anonymous function to have this
be the containing object, like so:
theElement.addEventListener("click", (event) => this.onClick(event));
In this case, I can't remove the anonymous function from the listening to the event. How do I have an event listener as part of a class (with access to private fields and methods), that I can remove later?
First, JavaScript and TypeScript behave the exact same way even if you write like that:
theElement.addEventListener("click", onClick);
Second, this is how you can retain a reference to an anonymous function:
var f = (event) => this.onClick(event);
theElement.addEventListener("click", f);
// later
theElement.removeEventListener("click", f);
If you're dealing with event listeners, there's a useful pattern for your class methods to be bound:
class MyClass {
init(theElement) {
theElement.addEventListener("click", this.onClick);
theElement.addEventListener("click", this.onClick2);
}
print() {
console.log("print");
}
onClick() {
this.print() // possible error (`this` is not guaranteed to be MyClass)
}
onClick2 = () => {
this.print() // no error, `this` is guaranteed to be of type MyClass
}
}
Keep in mind, however, that this code will create a separate function onClick2
for every object of class MyClass
. That can negatively affect your memory usage, if you create lots of MyClass
instances and rarely use their onClick
listeners.