Often when using a callback you want access to a specific context.
function SomeClass(msg, elem) {
this.msg = msg;
elem.addEventListener('click', function() {
console.log(this.msg); // <= will fail because "this" is undefined
});
}
var s = new SomeClass("hello", someElement);
Use bind
bind
effectively generates a new function that sets this
to whatever
was passed to bind
then calls the original function.
function SomeClass(msg, elem) {
this.msg = msg;
elem.addEventListener('click', function() {
console.log(this.msg);
}.bind(this)); // <=- bind the function to `this`
}
Use arrow functions
Arrow functions automatically bind the current this
context.
function SomeClass(msg, elem) {
this.msg = msg;
elem.addEventListener('click',() => { // <=- arrow function binds `this`
console.log(this.msg);
});
}
Often you'd like to call a member function, ideally passing any arguments that were passed to the event on to the function.
Use bind
function SomeClass(msg, elem) {
this.msg = msg;
elem.addEventListener('click', this.handleClick.bind(this));
}
SomeClass.prototype.handleClick = function(event) {
console.log(event.type, this.msg);
};
Use arrow functions and the rest operator
function SomeClass(msg, elem) {
this.msg = msg;
elem.addEventListener('click', (...a) => this.handleClick(...a));
}
SomeClass.prototype.handleClick = function(event) {
console.log(event.type, this.msg);
};
For DOM event listeners in particular you can implement the EventListener
interface
function SomeClass(msg, elem) {
this.msg = msg;
elem.addEventListener('click', this);
}
SomeClass.prototype.handleEvent = function(event) {
var fn = this[event.type];
if (fn) {
fn.apply(this, arguments);
}
};
SomeClass.prototype.click = function(event) {
console.log(this.msg);
};