Closures in a loop are causing me problems. I think I have to make another function that returns a function to solve the problem, but I can\'t get it to work with my jQuery
@Andy solution is the nicest. But you can also use Javascript scoping to help you save the value in your closure.
You do so by creating a new scope in your loop body by executing an anonymous function.
for (var i = 0; i < 3; i++) {
(function(){
var index = i;
$('#button'+index).click(function(){
foo(index);
});
})();
}
Since the loop body is a new scope at each iteration, the index variable is duplicated with the correct value at each iteration.
Or just manufacture a new function, as you describe. It would look like this:
function foo(val) {
return function() {
alert(val);
}
}
for (var i = 0; i < 3; i++) {
$('#button'+i).click(foo(i));
}
I'm pretty sure Mehrdad's solution doesn't work. When you see people copying to a temporary variable, it's usually to save the value of "this" which may be different within an inner child scope.
Use the .each function from jquery - I guess you a looping through similar elements - so add the click using something like:
$(element).children(class).each(function(i){
$(this).click(function(){
foo(i);
});
});
Not tested but I always use this kind structure where possible.
See the bind method.
$('#button'+i).bind('click', {button: i}, function(event) {
foo(event.data.button);
});
From the docs:
The optional eventData parameter is not commonly used. When provided, this argument allows us to pass additional information to the handler. One handy use of this parameter is to work around issues caused by closures
Try this code:
function foo(val) {
alert(val);
}
var funMaker = function(k) {
return function() {
foo(k);
};
};
for (var i = 0; i < 3; i++) {
$('#button'+i).click(funMaker(i));
}
Some important points here:
i
is copied in a new scope as k
, and the function returned from funMaker
closes around k
(which doesn't change in the loop), not around i
(which does).click
doesn't 'own' the i
, it closes over the i
of its creator, and that i
changes in the loop.funMaker
inlined, but I usually use such helper functions to make things clearer.funMaker
is k
, but that makes no difference, it could have been i
without any problems, since it exists in the scope of the function funMaker
.EDIT: Fixed some punctuation.