6

Possible Duplicate:
Javascript closure inside loops - simple practical example
javascript variable scope/closure in loop after timeout

Can you please explain step by step why the results are different?

Snippet A (alerts 10)

for(var i=0; i<10; i++) if(i==3) setTimeout(function() {alert(i);}, 100);

Snippet B (alerts 3)

for(var i=0; i<10; i++) if(i==3) setTimeout((function(p) {
   return function() {alert(p);}
} )(i), 100);
Community
  • 1
  • 1
Jan Turoň
  • 31,451
  • 23
  • 125
  • 169
  • 1
    This basic issue has been the subject of hundreds of questions here. The answer is simple: the `i` referenced in the timeout handler is the `i` from the outer scope, and it's being changed by the loop. That is, there is only one `i` involved. – Pointy Nov 25 '12 at 17:20
  • 2
    @Pointy Find a duplicate and flag it then. – Vala Nov 25 '12 at 17:21
  • Basically start typing in a question with the words "javascript", "loop", and "timeout" or "handler". – Pointy Nov 25 '12 at 17:23

1 Answers1

4

A variable's scope is either the global scope (window in a browser) or a function.

In the first case i is defined in the scope containing the for loop. This is why it still changes until the end of the loop before the callback given to setTimeout is executed.

In the second case, the intermediate function contains and keeps another variable, p. Note that this would have worked without the test, as this would have been a different closure for each setTimeout.

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • Oh, I see. I suppose the argument is always passed by reference, right? – Jan Turoň Nov 25 '12 at 17:24
  • 1
    No, they're always passed by value but i isn't passed, in the first case, until the alert is called. At this time the loop has ended. But be careful with "passed by value vs passed by reference" : it's clear for a primitive type but the value of a variable can be a reference to an object. – Denys Séguret Nov 25 '12 at 17:27