Hello-World
Hello-World

Reputation: 9555

how to create new callback function

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

Answers (3)

jfriend00
jfriend00

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

gstroup
gstroup

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

Smeegs
Smeegs

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

Related Questions