Reputation: 2429
In continuation to this question, I tried the following code that uses the same variable in both the loops and I get the desired result. My question is, WHY ?
So the initial code is:
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](); // this will not give desired output
}
The outputs this:
Whereas, the intended output is:
Now, if I use variable 'i' (a global variable) in the second loop as well, the code looks like:
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 ( i = 0; i < 3; i++) {
funcs[i](); // this gives desired output
}
I get the intended output,
WHY?
Upvotes: 3
Views: 61
Reputation: 2850
Now, if I use variable 'i' (a global variable) in the second loop as well ... I get the intended output ... WHY?
Because when you do the first executing loop:
for (var j = 0; j < 3; j++) {
funcs[j]();
}
the loop constructing the array has finished and the global variable i
has the value 3
and therefore console.log(i)
results in logging 3
to the console for each iteration of the first executing loop. When you do the second executing loop:
for ( i = 0; i < 3; i++) {
funcs[i]();
}
you for each iteration of the loop assign a new value to the global variable i
and it is this new value that the console.log(i)
will log to the console: 0, 1, 2.
You can use let
to achieve the desired result in a simple way:
"use strict"; // use of let requires strict mode
var funcs = [];
for (let i = 0; i < 3; i++) { // just replace var with let here
funcs[i] = function() {
console.log("My value: " + i);
};
}
for (var j = 0; j < 3; j++) {
funcs[j]();
}
Now the array will be constructed with functions having access to a local variable, which is assigned the value of i
at the time of adding the function to the array.
Upvotes: 2
Reputation: 5625
Because the variable i
is contaminated. In your snippets, The loops write to the same variable i
and the functions reads it. Note that there is just one variable i
in your code.
What you really need to get your intended result is called "module pattern", which wraps a function to keep a local copy of the variable in the loop:
for (var i=0; i<3; i++) {
(function (j) {
funcs[j] = function() { // and store them in funcs
console.log("My value: " + j); // each should log its value.
};
})(i);
}
You can read this article to get more information about "module pattern".
Upvotes: 1