闭包
利用闭包将每一次循环中的 i 保存起来,等待延时器回调函数获取。
for(var i = 0; i < 6; i++){
setTimeout(function generatorFunc (i) {
return function sonFunc () {
console.log(i)
}
}(i), 1000)
}
- generatorFunc 是一个立即执行函数,接受一个参数并返回一个函数 sonFunc 。sonFunc 作为延时器的回调函数。
- 在每次循环中,i 作为立即执行函数的参数传递给了 generatorFunc ,所以每次循环中的 i 都将成为当前次 generatorFunc 作用域的一个变量。
- 这个变量会被当前作用域中的 sonFunc 引用(形成闭包)。
- 也就是说 sonFunc(即 setTimeout 的回调函数)保有对 generatorFunc 作用域的引用(闭包)
- 这个引用将一直持续到延时器的回调函数 sonFunc 执行完毕之后才会销毁。
for(var i = 0; i < 6; i++){
(function (i) {
setTimeout(function () {
console.log(i)
}, 1000)
})(i)
}
这种方式的原理和方法一是一样的只不过位置不同。
let 块级作用域
for(let i = 0; i < 6; i++){
setTimeout(function () {
console.log(i)
}, 1000)
}
- 因为 let 是块级作用域,所以在每次循环迭代的过程中都会重新声明 i 变量,并将上一次的 i 的值赋给最新的 i 。
- 因为每次循环都是在新的块级作用域中执行,每个新的块级作用域都会有一个新的 i 变量,
- 所以也可以打印 012345