I just needed to use partial application to pass data into a callback, and I found I needed a layer of indirection to prevent subsequent runs of a loop from changing the data I'm passing to the callback.
See here for a very simple working example: http://jsfiddle.net/s5gVj/
(if the jsfiddle is self explanatory, feel free to skip straight to the question below)
Without the indirection
This will always set the label to "Button 1 pressed."
This happens regardless of which button was pressed.
for(var i = 0 ; i < buttons.length ; i++)
{
var buttonID = i;
$(buttons[i]).click(
function(e)
{
$("label").html("Button " + buttonID + " pressed.");
});
}
Indirectly, via a function
Meanwhile, using a function in the middle corrects the problem
For the first button, the result will be "Button 0 pressed"
For the second button, it will be "Button 1 pressed".
var buttonClickHandlerWithID =
function(buttonID)
{
return function(e)
{
$("label").html("Button " + buttonID + " pressed.");
}
}
for(var i = 0 ; i < buttons.length ; i++)
{
$(buttons[i]).click(buttonClickHandlerWithID(i));
}
Why does this happen? Is there something special about function calls that ensure the variable is copied and thus no longer a reference to the same data, or is there something else going on?
I expected a variable declared within the for loop to be recreated on each iteration, thus each iteration being separate, but I guess that isn't the case?