Closures in a for loop and lexical environment
Solution 1:
The i
inside your function is evaluated when the function is executed, not when you assign it to onload
. Your for loop has already completed by the time any of your onload
functions fire, so all of them see the final value N
.
To capture the current value of i
, you need to pass it as a parameter to another function where it can be captured as a local variable:
function captureI(i) {
return function () {
console.log("Image " + i + " loaded");
};
}
var images = [];
for (var i=1; i<N; i++) {
images[i] = new Image();
images[i].onload = captureI(i);
images[i].src = "image" + i + ".png";
}
This works because every time you call captureI
, a new local variable is created for that instance of captureI
. In essence, you are creating N
different variables and each onload
function captures a different instance of the variable.
Solution 2:
You can wrap it in a closure to avoid to use i
variable, which is a loop variable and thus changes:
(function(j) {
images[i].onload = function () {
console.log("Image " + i + ", " + j + " loaded");
};
})(i);
This demonstrates the difference between i
, which is a loop variable and changes, and j
, which is a function-bound parameter, which doesn't change.
See the jsfiddle here:
- http://jsfiddle.net/VuLTa/