let 解决了 var 在 for 循环中因函数作用域导致的闭包变量共享问题:var 共享同一变量绑定,异步回调均读取循环结束后的最终值;let 每次迭代创建新绑定,使每个回调捕获当轮的独立值。

用 let 声明循环变量,能避免传统 var 在 for 循环中因函数作用域导致的闭包变量共享问题。
为什么 var 在循环里会出问题
var 是函数作用域,且存在变量提升。在 for 循环中用 var 声明变量,整个循环共用同一个变量绑定。如果循环内创建了异步操作(比如 setTimeout 或事件监听器),所有回调都会引用循环结束后的最终值。
例如:
for (var i = 0; i console.log(i), 100); // 输出:3, 3, 3 }
因为循环结束时 i 已变成 3,三个定时器都读取这个值。
let 怎么解决这个问题
let 具有块级作用域,并且在每次循环迭代中,都会为变量创建一个**新的绑定**(不是拷贝值,而是独立的词法环境)。因此每个回调捕获的是各自迭代中对应的 i 值。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
改写上面的例子:
for (let i = 0; i console.log(i), 100); // 输出:0, 1, 2 }
这是因为每次迭代的 i 实际上是不同的绑定,每个 setTimeout 回调都闭包了自己那一轮的 i。
适用场景和注意事项
- 适用于
for、for...in、for...of循环,但不适用于while或do...while(需手动在块内用let) - 不能用
let声明同名变量多次,否则报错:Identifier 'i' has already been declared - 若在循环体外需要访问循环变量(比如想在循环后用
i),注意let声明的变量在循环块外不可访问 - 箭头函数或普通函数内部引用
let循环变量,无需额外处理,自然隔离
替代方案对比(了解即可)
不用 let 时,常见 workaround 有:
- 用立即执行函数(IIFE)+
var传参绑定 - 用
setTimeout的第三个参数传参(仅限支持该用法的 API) - 用
Array.from或map配合索引 —— 更函数式,天然避免变量复用
但这些都不如直接用 let 简洁、直观、符合直觉。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










