1: 闭包函数
定时器循环是异步编程, 每一轮循环设置定时器, 无需等定时器触发执行, 继续下一轮循环。
(定时器触发的时候,循环已经结束); 十次循环都已经结束了, 设置了十次定时器, 循环已经结束, 定时器还没有开始。
循环结束 i = 10;
for(var i=0, i<10, i++) {
setTimeout(()=> {
console.log(i);
}, 1000)
}
1: 修改为: let 存在块级作用域, 每一次循环都会在当前块级作用域中形成一个私有变量i, 存储索引值。
当定时器只当的时候, 所使用的i 就是所处在块级作用域中的 i
for(let i=0, i<10, i++) {
setTimeout(()=> {
console.log(i);
}, 1000)
}
2: 闭包解决;
// 方案一: 闭包解决
for(var i=0,i<10, i++) {
~function() {
setTimeout(()=> {
console.log(i)
}, 1000)
}(i);
}
// 方案二: 闭包解决
for(var i=0, i<10, i++) {
setTimeout((i)=> {
return ()=> {
return console.log(i)
}(i)
}, 1000)
}
// 方案三: 简写
for(var i=0, i<10, i++) {
setTimeout(i=>()=>console.log(i)(i), 1000);
}
// 方案四:
// 可以 基于bind 的预先处理机制: 在循环的时候就把每一次执行的函数需要输出的结果, 预先传给函数即可。
for(var i=0, i<10, i++) {
var fn = function(i) {
console.log(i);
}
setTimeout(fn.bind(null, i), 1000);
}