var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i); // i 指向全局的 i,也就是數組中函數全部的i都指向的是同一個變量i
};
}
a[6](); // 10
複製代碼
上面代碼中,變量i是var命令聲明的,在全局範圍內都有效,因此全局只有一個變量i。每一次循環,變量i的值都會自增,而循環內被賦給數組a的函數內部的console.log(i),裏面的i指向的就是全局的i。也就是說,全部數組a的成員裏面的i,指向的都是同一個i,致使運行時輸出的是循環結束以後i的值,也就是 10。數組
若是使用let,聲明的變量僅在塊級做用域內有效,最後輸出的是 6。閉包
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i); //因爲 let 建立的變量是塊級做用域的,因此在這個函數內每次都保存一個新的 i
};
}
a[6](); // 6
複製代碼
這是由於let 建立的變量是塊級做用域的,因此每次循環都是一個新的 i,每次的值都是 i++ 的結果。由於每次循環的 i 都是一個獨立的變量(內存裏的惟一地址),所以閉包記錄的值都是惟一的,因此才能獲得最終的結果函數
若是用 var 的話,變量 i 是一個全局變量,雖然循環體內每次都建立了一個函數來打印 i,可是當時當刻僅僅是一個指向全局變量 i 的指針,當循環結束以後不管你用哪個下標去訪問循環建立的閉包函數,打印的變量 i 都是全局的那一個,因此所有都是 10。ui