Reputation: 1341
a = [];
for (var i = 0; i < 3; i++) {
a.push(function() {
console.log(i);
})
}
a[0]() // I want 0, but I get 3
I am trying to write a simple piece of code where I have an array of functions such that when I execute a function at a particular index, the index value should get printed.
However, the piece of code above shows the same result (3 in this case) for all index values. I understand that the value is pointing by reference and therefore points to the last value of i. Could someone point out how to do this in the right manner?
Upvotes: 0
Views: 51
Reputation: 48630
Here is an alternate version to an anonymous function that gets created and executed all at once.
The issue that you are having is that when the function gets called, the loop has already been evaluated and the value of i
has already reached the max value of 3
. You need trap the current value of i
while the loop is being evaluated.
var a = [];
for (var i = 0; i < 3; i++) {
var fn = function() {
console.log(arguments.callee.i);
}
fn.i = i; // Pass as 'i' parameter to 'fn'.
a.push(fn);
}
a[0](); // The value 0 will be printed, rather than 3.
There is more than one way to skin a cat. The code above is very similar to:
var a = [];
function fn(i) {
return function() {
console.log(i);
}
}
for (var i = 0; i < 3; i++) {
a.push(fn(i));
}
a[0](); // The value 0 will be printed, rather than 3.
Upvotes: 0
Reputation: 10219
You can add a self executing function to act like a module. Doing this, the scope of the variable i
is in that function.
a = [];
for (var i = 0; i < 3; i++) {
(function(i){
a.push(function() {
alert(i);
})
})(i);
}
a[0]()
Note: In this block (function(i){ ... })(i)
, i
can have any name, there is no connection between i
from loop and i
from function, i.e. (function(r){ ... })(r)
.
Upvotes: 1
Reputation: 8488
Wrap it around a function. Now each time the loop executes, the wrapper function has its own value of i
.
a = [];
for (var i = 0; i < 3; i++) {
(function(i){
a.push(function() {
console.log(i);
})
})(i);
}
a[0]()
Upvotes: 2