Reputation: 9555
In the code below I'm adding a callback function essentially to a list in a loop.
every Item in the list that I call the call back it will log >>item30
can you please tell me why? Is there a way create a new function()
as the call back so
that it can log
item0
item1
item2
item3
item4
and so on .......
......
for (var j = 0 ; j < 30 ; j += 1) {
addThisThingtoList(function () {
console.log( "item" +j );
});
}
Upvotes: 1
Views: 69
Reputation: 707436
This only happens if your function addThisThingtoList()
is using asynchronous behavior (like Ajax calls) and thus its callback is called some time later after the for
loop has completely run its course and thus it's index value is at the ending value.
You can fix that with a closure that will freeze the loop value separately for each call to addThisThingtoList()
like this:
for (var j = 0 ; j < 30 ; j += 1) {
(function(index) {
addThisThingtoList(function () {
console.log( "item" + index);
});
})(j);
}
Working demo: http://jsfiddle.net/jfriend00/A5cJG/
By way of explanation, this is an IIFE (immediately invoked function expression). The variable j
is passed to the IIFE and it becomes a named argument to the function that I named index
. Then, inside that function, you can refer to index
as the value of j
that is frozen uniquely and separately for each call to addThisThingtoList()
. I could have named the argument index
to also be j
in which case it would have just overriden the higher scoped j
, but I prefer to use a separate variable name to be more clear about what is what.
Here's a good reference on the IIFE concept if you want to read more about it:
http://benalman.com/news/2010/11/immediately-invoked-function-expression/
Upvotes: 2
Reputation: 1064
It's a classic javascript scope bug. You need to pass in the j variable to your function:
addThisThingToList(function(j) {
console.log("item" + j);
});
As @Smeegs says, "this is what closure is all about."
Upvotes: 0
Reputation: 9224
This is what closure is all about.
When you call the function, it pulls the value of j
at the time it's called, not at the time when it was added to the list.
So by the time you start calling the functions, j is already at 30.
Upvotes: 1