What will be logged to the console?
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Before we analyze the code snippet, let’s try to simplify it by removing the setTimeout
.
If we just leave the plain console.log
in the loop, then the output is all the values of i
from 0
to 4
printed on each iteration of the loop.
However, when the setTimeout
is added, the console.log
will be executed after the loop has already been processed and the value of i
is 5.
As i
was declared with var
, it has the global scope and the intermediary values aren’t stored in closure around the arrow function () => console.log(i)
.
ANSWER: the value 5
will be printed on the screen 5 times. Each time on the new line.
Top comments (4)
It should be noted that to get the intended outcome of printing
0
to4
, you can declarei
withlet
instead ofvar
.This will give the variable
i
block scoping instead of function scoping and will preventi
from being hoisted to the global scope. ThesetTimeout
function is an asynchronous function and since JavaScript is single-threaded, thesetTimeout
is passed to the browser's web api (which handles asynchronous functions) along with any bound variables. Declaringi
withvar
does not bind it withsetTimeout
; instead it gets hoisted and the for-loop iterates all five loops before thesetTimeout
's callback is executed resulting ini
equaling5
by the time it is called thus printing5
five times. By declaringi
withlet
,i
gets binded to thesetTimeout
so when it is passed, each callback function that gets passed into the task queue has its owni
with the value that was passed in during the for-loop iterations thus printing0
-4
.What's the implication on performance?
The question here isn't as much about performance, it's about properly understanding the way asynchronous operations work in JS.
JavaScript is async by design. There are no immediate problems with it if applied correctly.