Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript for loop unexpected behaviour

I have couple of questions about the javascript for loop.

First question:

for (i=0; i<=2; i++) {;}
console.log(i);

Output is 3. Shouldn't it be 2?

Second question:

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

Timeouts are set correctly: 0, 1000 and 2000. But the output is 3,3,3 (should be 0, 1, 2). Does this mean the delayed functions are executed after the loop exits? Why?

What should I read to understand all this mysterious javascript stuff?

Thank you.

like image 372
mgs Avatar asked Jul 03 '10 06:07

mgs


1 Answers

First question:

No because the i variable is incremented after the last successful iteration, then the condition is checked and it evaluates to false so the loop ends.

The for statement is composed by:

for ([initialExpression]; [condition]; [incrementExpression])
  statement

And it is executed in the following steps:

  1. The initialExpression is evaluated at the start
  2. The condition is evaluated, if it evaluates to false, the loop ends, if it evaluates to true, the statement is evaluated.
  3. Evaluate the statement.
  4. The incrementExpression is evaluated, go to step 2.

Second question:

The function is executed asynchronously after the loop has ended, at this time as you know i contains 3.

The common workaround for this is to use a function to preserve the value of the looping variable on each iteration, for example:

for (var i=0; i<=2; i++) {
  (function (i) {
    setTimeout(function(){console.log(i);}, i*1000);
  })(i);
}
like image 107
Christian C. Salvadó Avatar answered Oct 18 '22 17:10

Christian C. Salvadó