JavaScript var v.s let

const arr1 = [];
for(var i = 0; i < 3; ++i) {
  arr1.push(() => i);
}
const arr2 = arr1.map(x => x());
const arr3 = [];
for(let i = 0; i < 3; ++i) {
  arr3.push(() => i);
}
const arr4 = arr3.map(x => x());
console.log(arr1);
console.log(arr2);
console.log(arr3);
console.log(arr4);

var 和 let 的不同可以看這段代碼的結果。arr1.push(() => i); 因為這邊是回傳函式,函式抓到的i,會是for跑完後的i的值。
arr3.push(() => i) 這時候抓到的i就是區塊級作用域(Block Scope),為循環本體的每一次執行都產生一個作用域。

console.log(a); // undefined
console.log(b); //ReferenceError
var a = 1;
let b = 2;

還有幾個重點
1. let 有暫時死區

參考閱讀
Differences Between var and let