题目
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 的值。