Working with for loops are always complicated, mostly for-loops inside async blocks.


so here are some examples where i felt OMG, what is happening,

Example 1
for(var i=0; i<3; i++) {
	setTimeout(()=>console.log(i));
}
Output:
3
3
3

How?

Lexical scoping and closures:

On compilation time, javascript engine split the code into meaningful units and each will have it's on scopes, each unit will push to the event queue and event loop will start executing. Since Javascript is block scope; where var has global scope i will increment up to 3, by the time may be first setTimeout() may execute and will print 3, and next setTimeout() call prints another 3 and so on.

Use of let or const will avoid this issue. since i is lexically scoped each time when iterating i, so setTimeout() will only get that value for each iteration.

Example 2
for(let i=0; i<3; i++) {
	setTimeout(()=>console.log(i));
}
Output:
0
1
2
Example 3
for(let i= (setTimeout(()=>console.log(i)),0); i<3; i++) {
	i++;
}
Output:
0
0
0

In Example 3, setTimeout(()=>console.log(i) this will create its own lexical scope and it will only get i as 0.

Happy coding! 🙌