Reputation: 48753
Variables passed to closure by reference. This code:
var figs = ['circle', 'square'];
for (var i in figs) {
var fig = figs[i];
document.getElementById(fig).addEventListener("click", function(e) {
console.log(fig);
}, false);
}
always log last array element even you click to circle (square, last value of fig variable).
In order to bind actual value of fig variable I use wrapping in function call (so intermediate closure hold loop value):
var figs = ['circle', 'square'];
for (var i in figs) {
var fig = figs[i];
document.getElementById(fig).addEventListener("click", (function(fig) {
return function(e) {
console.log(fig);
}
})(fig), false);
}
Is that possible to avoid wrapping-function in order to pass by value?
UPDATE related questions and answers:
Upvotes: 1
Views: 448
Reputation: 43718
You can also use bind
and pass an object that encapsulates the variables you need. Then you can make use of this.fig
inside the handler to reference your figure.
document.getElementById(fig).addEventListener("click", (function(e) {
console.log(this.fig);
}).bind({ fig: fig }), false);
You can also bind a primitive value directly, however it will be wrapped in it's respective object wrapper e.g. Number
for a number, String
for a string, etc.
document.getElementById(fig).addEventListener("click", (function(e) {
//this will be the same as new String(fig)
}).bind(fig), false);
Upvotes: 2
Reputation: 237865
No, it is not possible.
However, you can make your code a bit nicer, by taking the code that produces the inner function out of the loop:
var figs = ['circle', 'square'];
function createFigHandler(fig) {
return function(e) {
console.log(fig);
}
}
for (var i = 0; i < figs.length; i++) {
var fig = figs[i];
document.getElementById(fig).addEventListener("click", createFigHandler(fig), false);
}
Upvotes: 4