0

My understanding of Javascript is that variables have function scope, not block scope, so variables declared inside a block are hoisted to the function above it. This article gives the following code example:

var arr = [1, 2, 3, 4]  
for(var i = 0; i < arr.length; i++) { 
  var entry = arr[i];
  setTimeout(function() {
    console.log(entry);
  }, 100);
}

The article states the the code gets translated into the following, and so the variable entry is common between each iteration. The result is that 4 is logged to the console four times

var arr, i, len, entry;
arr = [1, 2, 3, 4]  
for(i = 0; i < arr.length; i++) {  
  entry = arr[i];
  setTimeout(function() {
    console.log(entry);
  }, 100);
}

My question is, how should I rewrite the code if I want each call to setTimeout to log a different value from arr?

Zeophlite
  • 1,607
  • 3
  • 19
  • 36

1 Answers1

6

You can change the setTimeout to:

setTimeout(
   (function()
      {
          var entry = arr[i];
          return function() {console.log(entry);}
      }
   )()
);

That way, you create a new scope, and entry is in that scope.

You can also do:

(function(e)
    {
        setTimeout(function(){console.log(e);});
    }
)(entry);

Which also creates a new scope, in which e lies.

Yet another option:

setTimeout(
    (function(e)
        {
            return function() {console.log(e);};
        }
    )(entry);
);

In all cases, you use an anonymous function that you call immediately, so the only side-effect is that you are creating a new scope.

(edit: reformated a bit for readability, and added a bit more explanations)

jcaron
  • 17,302
  • 6
  • 32
  • 46