There is a difference of the scope with let
and var
, which causes them to behave differently.
Here is a quote from other Stack Overflow answer about the differences between var
and let
.
The main difference is scoping rules. Variables declared by var
keyword are scoped to the immediate function body (hence the function scope) while let
variables are scoped to the immediate enclosing block denoted by { }
(hence the block scope).
So, in summary, var
is referring to the same variable address. But, as let
is blocked scope (according to the quote above), every callback in setTimeout()
will make i
have a different value then the previous one.
An experiment that is possible is to make let
behave like var
. To make let
behave like var
, you can use (and run) the code below.
To see how let
is behaving like var
, read ahead about var
hoisting!
let i;
for (i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1);
}
As we moved let
to the main scope, it behaves like var
(as var
is positioned at the top of the file with a value of undefined
at runtime).
This makes the let
variable behave like var
, making the output of the for
loop the same as if the let
variable was var
.
Thanks to Nick Vu for the experiment!
Here is a quick overview of var
hoisting below.
The actual code (shown below):
web = "stackoverflow.com";
var web;
Is understood as:
var web;
web = "stackoverflow.com";
Basically, defining a variable with var
anywhere will always result it being at the top of the file, resulting in the weird behaviour with the for
loop.
This is why many people prefer let
over var
; because of how confusing var
hoisting can be!
Always use let
, unless var
is absolutely needed!
let
and block scoping with for loops – Orwin