โscopes matter with closures
const { log } = console;
// โญโโ i โโโฎ <--- โญ `i` is "block-scoped"
for (let i = 0; i < 3; i++) {
// โญ every time "block scope" is entered,
// a new/different `i` is captured by closure.
//
// โญโ closure โโโฎ
setTimeout( () => log(i) , 1000); // 0, 1, 2 โญ
}
let j = 0; // โ `j` is in "outer scope"
for ( ; j < 3; j++) {
// โ every closure is capturing the same `j` variable
//
// โญโ closure โโโฎ
setTimeout( () => log(j) , 2000); // 3, 3, 3 โ (j = 3 after for-loop)
}
var keep1 = [];
// โญโโ i โโโฎ <--- โ "var" has no block scope
for (var i = 0; i < 3; i++) {
// โ every closure is keeping the "same" `i`.
keep1[i] = function keepI(){
return i;
};
}
var keep2 = [];
// โญโโ i โโโฎ <--- โญ "let" is block-scoped
for (let i = 0; i < 3; i++) {
// โญ `i` is block-scoped, every time block scope is entered,
// a new/different `i` is created & kept by closure.
keep2[i] = function keepI(){
return i;
};
}
[
keep1.map(f => f()), // โ [ 3, 3, 3 ]
keep2.map(f => f()), // โญ [ 0, 1, 2 ]
].forEach(x => log(x));Last updated