for循環中的let與var的說明

  • 2020 年 10 月 31 日
  • 筆記
參考資料:《JavaScript高級程序設計》
 
在 let 出現之前,for 循環定義的迭代變量會滲透到循環體外部:
for (var i = 0; i < 5; ++i) {
// 循環邏輯
}
console.log(i); // 5
改成使用 let 之後,這個問題就消失了,因為迭代變量的作用域僅限於 for 循環塊內部:
for (let i = 0; i < 5; ++i) {
// 循環邏輯
}
console.log(i); // ReferenceError: i 沒有定義
在使用 var 的時候,最常見的問題就是對迭代變量的奇特聲明和修改:
for (var i = 0; i < 5; ++i) {
setTimeout(() => console.log(i), 0)
}
// 你可能以為會輸出 0、1、2、3、4
// 實際上會輸出 5、5、5、5、5
 
之所以會這樣,是因為在退出循環時,迭代變量保存的是導致循環退出的值:5。
在之後執行超時邏輯時,所有的 i 都是同一個變量,因而輸出的都是同一個最終值。
而在使用 let 聲明迭代變量時,JavaScript 引擎在後台會為每個迭代循環聲明一個新的迭代變量。
每個 setTimeout 引用的都是不同的變量實例,所以 console.log 輸出的是我們期望的值,也就是循
環執行過程中每個迭代變量的值。
 
for (let i = 0; i < 5; ++i) {
setTimeout(() => console.log(i), 0)
}
 
// 會輸出 0、1、2、3、4
 
這種每次迭代聲明一個獨立變量實例的行為適用於所有風格的 for 循環,包括 for-in 和 for-of
循環。