es5中使用在
for-in
for
迴圈中註冊非同步事件,非同步事件中的i
總是最後一個值。使用es6的let
const
可以解決
let obj = {
a: 1,
b: 1,
c: 1
}
// es5 for迴圈中 var宣告 i
let funcs = []
for (var key in obj) {
funcs.push(() => {
console.log(key)
})
}
funcs.forEach(func => {
func()
})
// c c c
// es6 for迴圈中 let宣告 i
let funcs1 = []
for (let key in obj) {
funcs1.push(() => {
console.log(key)
})
}
funcs1.forEach(func => {
func()
})
// a b c
複製程式碼
每次迴圈時,let
會宣告都會建立一個新變數key
,並將其初始化為key
的當前值,所以迴圈內部建立的每個函式都能得到屬於他們自己的i的副本。
值得一提的是,let
宣告再迴圈內部的行為是標準中專門定義的,他不一定與let
的不提升特性有關係,事實上,早起的let實現並不包含這一行為,是後來加入的。
而下邊這個例子也證實了這一流程
let funcs1 = []
for (const key in obj) {
funcs1.push(() => {
console.log(key)
})
}
funcs1.forEach(func => {
func()
})
// a b c
複製程式碼
const
定義的key
是不能重新賦值的,但在迴圈中一直變化,並沒有報錯。是因為每次迭代都是新建立一個變數而不是修改已有變數
但const
在下面迴圈中會報錯,因為迭代一次後,i++
修改了const
宣告的i
let funcs = []
let arr = [1, 2, 3]
for (const i = 0; i < arr.length; i++) {
funcs.push(function () {i
console.log(i)
})
}
funcs.forEach(() => {
func()
})
// 1 2 3
複製程式碼