for (id = 50; id < 100; id++)
{
if($('#'+id).attr('class') == 'myField')
{
$('#'+id).bind('click', function() { install(id); } );
}
}
No idea why id can’t reach ‘install’ in function(). I am trying to bind every button (id from 50 to 100) with a click event to trigger the install(id) function. But it seems the variable id cannot reach install function. While I hard code it:
for (id = 50; id < 100; id++)
{
if($('#'+id).attr('class') == 'myField')
{
$('#'+id).bind('click', function() { install( 56 ); });
}
}
it works! Please tell me why.
What you made is one of the most common mistakes when using Javascript closures.
By the way the very fact that this mistake is so common is IMO a proof that it’s indeed a “bug” in the language itself.
Javascript supports read-write closures so when you capture a variable in a closure it’s not the current value of the variable that is captured, but the variable itself.
This means that for example in
each of the 10 functions in the array will contain a closure, but all of them will be referencing the same
ivariable used in the loop, not the value that this variable was having at the time the closure was created. So if you call any of them the output will be the same (for example10if you call them right after the loop).Luckily enough the workaround is simple:
using this “wrapping” you are calling an anonymous function and inside that function the variable
iis a different one from the loop and is actually a different variable for each invocation. Inside that functioniis just a parameter and the closure returned is bound to that parameter.In your case the solution is therefore: