Like was previously said here: JavaScript closure inside loops – simple practical example
The output for this code is always 3
var funcs = [];
for (var i = 0; i < 3; i++) { // let's create 3 functions
funcs[i] = function() { // and store them in funcs
console.log("My value: " + i); // each should log its value.
};
}
for (var j = 0; j < 3; j++) {
funcs[j](); // and now let's run each one to see
}
// My value: 3
// My value: 3
// My value: 3
This happens is because there's no difference between the global i
and the i
inside the anonymous function of the loop. So that when funcs[i]
gets called, its current value is already 3
.
The classic way to solve this is via a closure.
var funcs = [];
function createfunc(i) {
return function() { console.log("My value: " + i); };
}
for (var i = 0; i < 3; i++) {
funcs[i] = createfunc(i);
}
for (var j = 0; j < 3; j++) {
funcs[j](); // and now let's run each one to see
}
By wrapping the function creation in the createfunc(i)
function, you ensure that the value of "i" is bound to an unchanging value outside the function.
One way to solve this and that I don't get is through the creation of a let
variable.
var funcs = [];
for (let i = 0; i < 3; i++) {
funcs[i] = function() {
console.log("My value: " + i);
};
}
funcs[0]();
funcs[1]();
funcs[2]();
funcs[3]();
By doing so, I'd expect the variable let
to be only accessible inside the loop, hence at the time I'm calling the function i
is still undefined
.
Since it works, it looks like JS is able to assign the proper variable i
while still in the for loop and at the time I invoke the function it has the proper value i
assigned.
What am I missing?