0
var i;
var print = function(){
  console.log(i);
};
for(i = 0 ; i<10;i++){
 setTimeout(print,1000);
};

It prints 10 ten times i cannot understand why?

Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252
Abhinav rawat
  • 111
  • 2
  • 13

3 Answers3

0

The setTimeout is an asynchronous call. That means, it gets executed only after the whole loop gets executed. In your JS Interpreter, it would be like this:

 1: for loop.                               // i = 0
 2: send setTimeout #1.     increment i.    // i = 1
 3: send setTimeout #2.     increment i.    // i = 2
 4: send setTimeout #3.     increment i.    // i = 3
 5: send setTimeout #4.     increment i.    // i = 4
 6: send setTimeout #5.     increment i.    // i = 5
 7: send setTimeout #6.     increment i.    // i = 6
 8: send setTimeout #7.     increment i.    // i = 7
 9: send setTimeout #8.     increment i.    // i = 8
10: send setTimeout #9.     increment i.    // i = 9
11: send setTimeout #10.    increment i.    // i = 10
12: finish for loop.                        // i = 10
13: exec setTimeout #1.                     // i = 10
14: exec setTimeout #2.                     // i = 10
15: exec setTimeout #3.                     // i = 10
16: exec setTimeout #4.                     // i = 10
17: exec setTimeout #5.                     // i = 10
18: exec setTimeout #6.                     // i = 10
19: exec setTimeout #7.                     // i = 10
20: exec setTimeout #8.                     // i = 10
21: exec setTimeout #9.                     // i = 10
22: exec setTimeout #10.                    // i = 10

When the execution phase happens, i would have already 10.

The right way to do this is using Closures. They maintain the environment value by packing the variable's value.

var i;
var print = function(i) {
  console.log(i);
};
for (i = 0; i < 10; i++) {
  (function (a) {
    setTimeout(function () {
      print(a);
    }, 1000);
  })(i);
}
Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252
0

This is because of JavaScript event loop. All your setTimeouts are stacked at that end of the queue of event loop. Once your for loop finished(by the time when i has already increase to 10) , all setTimeouts starts executing. Hence you see 10 printed all the time.

Don
  • 1,334
  • 1
  • 10
  • 18
0

n value is picked from the closure. It contains the value = 1,2,3... while creation of the function.

var i ;
var print = function(n){
  console.log(n);
};
for(i = 0 ; i<10;i++){
 setTimeout((function(n){
   return function () {
     print(n);  
   }
 })(i),1000);
};
Ayan
  • 2,300
  • 1
  • 13
  • 28