4

I am trying to set several timeouts inside a loop where the parameter function of setTimeout uses diferent values (depending of the loop index) as parameter. This is a simplificated example:

for(i=0; i<5; i++) 
{   
    var m = setTimeout( function () {console.log(i)}, (i+1)*2000 );
} 

I thought that with the code above I get "0, 1, 2, 3, 4" every 2 seconds. Instead of this I get "5, 5, 5, 5, 5" every 2 seconds. Why?

2 Answers2

3

If you're happy to restrict support to modern web browsers (i.e. not IE 9 and earlier) the below will work:

for(i=0; i<5; i++) 
{   
    var m = setTimeout( function (i) {console.log(i)}, (i+1)*2000, i );
}

You can pass your variable as a third argument to setTimeout and then receive it in your setTimeout function.

As for why your original code doesn't work, it has to do with Javascript scope which is explained quite well here: What is lexical scope?

Community
  • 1
  • 1
Matt McDonald
  • 4,791
  • 2
  • 34
  • 55
1

You need a wrapper function to create a closure and keep value of i at the moment of iteration:

for(i=0; i<5; i++) {
    (function(timeout) {
        var m = setTimeout( function () {console.log(timeout)}, (timeout+1)*2000 );
    })(i)        
}
Nikolay Ermakov
  • 5,031
  • 2
  • 11
  • 18