題目
for(var i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i)
}, 1000)
}
方法
// 方法1:使用let形成塊級作用域
for(let i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i)
}, 1000)
}
// 方法2:閉包,借助閉包為每次循環形成一個單獨的作用域以保存變量
for(var i = 0; i < 3; i++) {
(function(i) {
setTimeout(function() {
console.log(i)
}, 1000)
})(i)
}
// 方法3:settimeout 內部閉包,注意:不要將參數傳入 return 的函數中,否則,這樣無法形成閉包
for(var i = 0; i < 3; i++) {
setTimeout((function(i) {
return function () {
console.log(i)
}
})(i), 1000)
}
// 方法4:bind
for(var i = 0; i < 3; i++) {
setTimeout(function(i) {
console.log(i)
}.bind(null, i), 1000)
}
// 方法5:借助外層函數保存變量
function output(i) {
setTimeout(function() {
console.log(i)
}, 1000)
}
for(var i = 0; i < 3; i++) {
output(i)
}
總結
由于題目中循環(for(var i...))無法形成作用域,每次循環產生的 i 的值就無法得以保留。各種方法的本質在于利用 let,閉包等形成作用域以保留 i 的值。