If you want to pass one variable but keep the this
context, then you can use currying or partial application:
Your function has to receive a value and return another function. This way you can do the following:
function callback(num) {
return function() {
console.log(num);
console.log(this.id);
}
}
var number = 1;
document.getElementById("hello").addEventListener("click", callback(number));
//change the variable
number = 2;
document.getElementById("world").addEventListener("click", callback(number));
//change the variable again
number = 3;
<button id="hello">Hello</button>
<button id="world">World</button>
Same idea but instead of having your callback return a new function, it will just take a single argument and work normally, you need another function that will do the partial application:
function callback(num) {
console.log(num);
console.log(this.id);
}
var number = 1;
document.getElementById("hello").addEventListener("click", partial(callback, number));
//change the variable
number = 2;
document.getElementById("world").addEventListener("click", partial(callback, number));
//change the variable again
number = 3;
function partial(fn, arg) {
return function() {
return fn.call(this, arg);
}
}
<button id="hello">Hello</button>
<button id="world">World</button>
The partial application function can be generalised to handle any amount or arguments
In ES6:
function partial(fn, ...args) {
return function(...otherArgs) {
return fn.apply(this, [...args, ...otherArgs]);
}
}
In ES5:
function partial(fn) {
var args = [].prototype.slice.call(arguments, 1);
return function() {
var otherArgs = [].[].prototype.slice.call(arguments);
return fn.apply(this, args.concat(otherArgs));
}
}