用 let 替代 var 是解决循环中闭包变量状态错误的最简单有效方法,因其每次迭代创建独立块级绑定;其他方案包括 iife、settimeout 第三个参数传值、array.from 或 map 函数式遍历。

在循环中使用闭包保存正确的变量状态,核心是解决 var 声明导致的变量提升和共享问题。最常见的表现是:循环结束后所有回调都输出最后一个值(比如全打印 5 而不是 0 到 4)。
用 let 替代 var(最简单有效)
let 在每次循环迭代中创建块级作用域绑定,每个迭代都有独立的变量实例,天然避免闭包捕获问题。
✅ 正确写法:
for (let i = 0; i console.log(i), 100); // 输出 0, 1, 2, 3, 4 }
⚠️ 注意:let 的块级作用域只对当前迭代生效,不是“复制值”,而是为每次迭代生成新的绑定。
用立即执行函数(IIFE)包裹 var
如果必须用 var(如兼容旧环境),可通过 IIFE 将当前值作为参数传入,形成独立作用域。
✅ 正确写法:
for (var i = 0; i console.log(i), 100); })(i); }
? 关键点:把 i 作为形参传入,函数内部的 i 是独立副本,不受外部循环变量变化影响。
用 setTimeout 的第三个参数或箭头函数参数传递
利用 setTimeout 支持额外参数的特性,直接把当前值注入回调,避免闭包引用外部变量。
✅ 正确写法:
for (var i = 0; i
✅ 或者用箭头函数(更简洁):
for (var i = 0; i console.log(i), 100, i); }
用 Array.from 或 map 避免显式循环
把索引转为数组再遍历,天然基于函数式调用,每个元素处理都在独立作用域中进行。
✅ 推荐写法:
Array.from({ length: 5 }, (_, i) =>
setTimeout(() => console.log(i), 100)
);
✅ 或结合 keys():
[...Array(5).keys()].forEach(i => setTimeout(() => console.log(i), 100) );
本质上,问题不在于闭包本身,而在于变量声明方式与作用域的关系。现代代码优先用 let,既清晰又安全;历史项目可选 IIFE 或 setTimeout 参数传值方案。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











