avatar

在循环中使用闭包

面试

编写一个函数,该函数将遍历整数列表,并在延迟3秒后打印每个元素的索引。

经常不正确的写法是这样的:

1
2
3
4
5
6
7
8
const arr = [1, 2, 3, 4, 5];

for (var i = 0; i < arr.length; i++) {
setTimeout(function() {
console.log(i);
}, 3000);
}
// 如果运行上面的代码, 3秒后你会看到 打印 5个5, 而不是0,1,2,3,4

原因是因为 setTimeout 函数创建了一个可以访问其外部作用域的函数(闭包),该作用域是包含索引 i 的循环。 经过 3 秒后,执行该函数并打印出 i 的值,该值在循环结束时为 4,因为它循环经过0,1,2,3,4并且循环最终停止在 4。

实际上有多处方法来正确的解这道题:

1
2
3
4
5
6
7
8
9
const arr = [1, 2, 3, 4, 5];

for (var i = 0; i < arr.length; i++) {
setTimeout(function(i_local){
return function () {
console.log(i_local);
}
}(i), 3000)
}

或者

1
2
3
4
5
6
7
const arr = [1, 2, 3, 4, 5];

for (let i = 0; i < arr.length; i++) {
setTimeout(function(){
console.log(i);
}, 3000)
}
文章作者: Kwin
文章链接: http://huangkun.host/2020/03/25/20190927-在循环中使用闭包/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Kwin 's Blog
打赏
  • 微信
    微信
  • 支付宝
    支付宝

评论