Jafar Rasooli
Jafar Rasooli

Reputation: 3527

weird behavior in javascript execution timing

i was a reading book named async javascript , one of the example of this book tried to show that events in javascript will trigger when processor has no instruction to do in the same process . for the proof of his word he brought an example :

for (var i = 1; i <= 3; i++) {
  setTimeout(function(){ console.log(i); }, 0);
};

the output is :

4
4
4
4

everyhting is ok and i expected the result . but when i put the "console.log(i)" out of function the result will change .

for (var i = 1; i <= 3; i++) {
  setTimeout(console.log(i), 0);
};

the output is :

1
2
3

i don't know why the output is different in those examples . i know its about variable scopes , but don't know exactly the reason . i hope if someone can help.

Upvotes: 1

Views: 74

Answers (2)

Felix Kling
Felix Kling

Reputation: 816334

i don't know why the output is different in those examples

Because in the second case you are calling console.log(i) immediately and pass the return value undefined to setTimeout (instead of passing a function like in the first case).
Arguments are always evaluated first, so if you have foo(bar()), bar is called first and its return value is passed to foo.

You can verify this by adding console.log('after'); after the loop. In the first case, you should get

after
4
4
4

and in the second case, you will get

1
2
3
after

demonstrating that setTimeout is not adding anything to the event queue.

See also Calling functions with setTimeout()

i know its about variable scopes

Actually it's not, it's all about timing, the moment when console.log is executed.

Upvotes: 3

Mathias Dolidon
Mathias Dolidon

Reputation: 3903

When you call setTimeout(expr,t), expr gets evaluated, hoping it returns a function. In your second case console.log(...) doesn't return anything, but it gets evaluated nonetheless. What you see is the side-effect of this evaluation prior to passing the result to setTimeout.

Upvotes: 2

Related Questions