碰到一道題:
for(var i=0;i<2;i++){
setTimeout(function(){
console.log(i);
},100)
} //輸出結果為:2 2
for(let i=0;i<2;i++){ setTimeout(function(){ console.log(i); },100) } //輸出結果為:0 1
我們先從第一個for循環說起,setTImeout是異步執行的
因此setTImeout在異步隊列中,需要等待同步隊列(for循環)執行完成后才可進行,
此時,同步隊列執行完成后i為2,所以執行setTImeout時,輸出為2
接着看第二個for循環,由於i使用let定義的,let為塊級作用域,但按我們的正常理解,應該會得出上邊的結果
找了下網上,解釋如下:
for循環中的let,事實上將其重新綁定到每一個循環迭代中,在確保上一次循環迭代結束后才會進行下一步循環,重新賦值
簡單說就是let的for循環中,每次都需要保證循環體里的執行完畢后才會進行下一次循環(我是這么理解的)
又找了一個相似的例子
var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10
由於i是全局作用域,可被函數中的i獲取得到,所以數組函數中輸出的i均為10;
var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 6
而這里的i是塊級作用域,當前i只能在本輪循環中奇效,每次循環中的i均為一個新的變量,因此最終取出的值為6