let 声明循环变量可解决闭包中变量共享问题,因每次迭代创建独立词法绑定;var 因函数作用域导致所有回调共享同一变量,输出最终值;仅 for/for...of/for...in 配合 let/const 有效。

用 let 声明循环变量,是最直接、最可靠的解法。它不是靠“复制值”,而是每次迭代都创建一个独立的词法绑定,让每个回调自然捕获对应轮次的值。
为什么 var 会出问题
var 是函数作用域,整个 for 循环只声明一个 i 变量。所有异步操作(如 setTimeout、事件监听、fetch 回调)执行时,循环早已结束,i 已变成最终值(比如 5),所有回调读到的都是这个值。
- 所有回调共享同一个内存地址上的 i
- 即使循环跑了 5 次,i 还是那个 i
- 结果:本该输出 0、1、2、3、4,却全输出 5
let 是怎么解决的
for (let i = ...) 中的 i,在每次迭代开始时都会重新声明一个同名但独立的绑定。箭头函数或普通函数内部引用的 i,指向的就是当前轮次的那个绑定。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 不需要 IIFE、bind 或额外参数传值
- 语法简洁,语义清晰
- 不是闭包封装,而是语言层面的块级作用域机制
哪些写法真正有效
只有明确使用 for、for...of、for...in,且循环变量用 let(或 const)声明时,才触发该机制。
- ✅
for (let i = 0; i - ✅
for (const item of arr) { ... }—— 每个 item 都是本轮独立绑定 - ❌
let i = 0; while (i console.log(i), 100); i++; }—— i 始终是同一个变量,仍输出多个 5
实际开发中常见场景
这类问题在动态绑定事件、批量请求、生成回调函数时高频出现。
- 菜单项循环绑定 click,想打印对应序号 → 用 let 声明索引或元素
- 遍历按钮数组,为每个按钮设置不同行为 → let 声明循环变量或直接解构
- 循环调用 API,每个请求需携带当前 id → let 声明 id,then 回调里自然捕获正确值
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










