function Counter(buttonElement) {
this.clicks = 0;
this.handleEvent = function(event) {
switch (event.type) {
case 'click':
this.clicks++;
console.log("I was clicked " + this.clicks + " times." );
break;
//handle any other event types
}
};
buttonElement.addEventListener("click", this, false);
}
const myCounter = new Counter( someButtonElement );
(In case you wouldn't know: if an object is used as an event listener, its `handleEvent()` method will be called with that object bound to `this`. In a way, arrow functions are working around what had been already solved by this mechanism.)In addition, with the `handleEvent` approach, you need to handle all events within a single function. But it's fairly easy to create multiple functions within a single function scope and pass them to different event handlers, thus avoiding the need for the large (and potentially error-prone) switch statement if you end up needing to handle lots of events.
Have you found cases where `handleEvent` works better than just defining local variables within a function and just using those? It seems to me that you wouldn't even need arrow functions to take advantage of the natural power of closures in this context.
Regarding prototypes, mind how this shares methods between instances, rather than consuming (and locking) resources by individual closures created in each of the instances (which, when GC was still based on reference count, would also have meant memory leaks):
function Counter(buttonElement) {
this.clicked = 0;
buttonElement.addEventlistener("click", this, false);
}
Counter.prototype = {
reset: function() { this.clicked = 0; },
log: function() { concole.log("I was clicked " + this.clicked + " times."); },
handleEvent: function(event) { this.clicked++; this.log(); }
};