1. 程式人生 > >JS: 當 let 和 var 遇上for迴圈

JS: 當 let 和 var 遇上for迴圈

for (var i = 0; i < 2; i++) {
    setTimeout(() => {
        console.log(i);
    })
}

//2
//2

上圖程式碼的執行結果是兩個2。對非同步程式設計有所瞭解的可能都知道setTimeout裡的callback會在event loop的佇列裡堆積,知道i++操作完成。所以打印出兩個2。而這裡需要注意的是var i變數。因為沒有任何函式封裝,所以i將成為全域性變數。

for (let i = 0; i < 2; i++) {
    setTimeout(() => {
        console.log(i);
    })
}

//0
//1

當var被修改成let時,情況發生了改變。程式執行結果是1和2。首先需要認識到let和var在作用域上的差別。var被圈定在函式內,而let被圈定在任何有中括號的範圍內。雖然上圖的for迴圈沒有將i圈定在中括號內,但ES6仍然在此機制上給let設定了屬於自己的作用域。不止如此,因為結果打印出了0和1,我們能肯定每一個i的值都有一個屬於自己的作用域,i並沒有被新的值所覆蓋。當setTimeout的回撥被啟動時,函式會去外層的作用域尋找i的值,而兩個回撥都擁有不同的作用域所以導致每次獲取i的值都是不同的。