Here is a canonical sample illustrating the issue with local variables captured by closures:
var a = []
for (var i = 1; i <= 3; i++) {
a.push(() => i)
}
var v = a.map(f => f())
console.log(v)
The result is [ 4, 4, 4 ]
, so far so good.
But when qualifying i
with let
instead of var
:
var a = []
for (let i = 1; i <= 3; i++) {
a.push(() => i)
}
var v = a.map(f => f())
console.log(v)
we get [ 1, 2, 3 ]
.
I don't understand why: even though let
scopes i
to the for
loop, there is always a single i
for all the closures, so this should not changed anything.
And for me the for
loop with let
should be equivalent to:
var a = []
{ // Scope for the loop
let i = 1
do {
a.push(() => i)
}
while (++i <= 3)
}
var v = a.map(f => f())
console.log(v)
like AFAIK it is in C, C++, Java, C#... and which gives [ 4, 4, 4 ]
.
Obviously I'm wrong, so what am I missing?