闭包能解决循环中定时器取到错误值的问题,因var变量提升且共享作用域导致所有回调访问同一i终值;用iife传参或let声明可为每次迭代创建独立作用域,固化当前值。

JavaScript 中定时器(如 setTimeout 或 setInterval)常因变量提升、作用域共享导致“取到错误值”,典型表现是循环中所有定时器都输出最后一个值。闭包能解决这个问题,核心是让每次迭代拥有独立的作用域,把当前变量“封存”住。
为什么循环中直接用 var 会出错
用 var 声明的变量具有函数作用域,且会被提升。在 for 循环中,所有定时器回调共享同一个 i 变量。等定时器真正执行时,循环早已结束,i 已变成终值(比如 5)。
例如:
(错误写法)for (var i = 0; i console.log(i), 100); // 输出:3, 3, 3 }
用闭包手动捕获当前值(ES5 兼容方案)
通过立即执行函数(IIFE),把当前的 i 作为参数传入,形成一个新作用域,让每个定时器记住自己的那一份 i。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 参数名(如
current)和实参(i)绑定,避免被后续循环覆盖 - 回调中使用
current,它在闭包内保持不变
for (var i = 0; i console.log(current), 100); })(i); }
输出:0, 1, 2 ✅
用 let 替代 var(更简洁的现代写法)
let 声明具有块级作用域,每次循环都会创建一个新的绑定,相当于自动为每次迭代生成一个闭包环境。
- 无需手写 IIFE,代码更清晰
- 每个
let i在本次循环块中是独立的 - 兼容性注意:需支持 ES6 的运行环境
for (let i = 0; i console.log(i), 100); // 输出:0, 1, 2 }
封装成可复用的延迟执行工具(带上下文)
如果需要保存多个变量(比如 id、name),可构造一个闭包函数,把关键数据作为参数传入并固化:
function createTimer(id, name, delay) {
return setTimeout(() => {
console.log(`ID: ${id}, Name: ${name}`);
}, delay);
}
for (let i = 0; i
<p>输出:<code>ID: 0, Name: item0</code> 和 <code>ID: 1, Name: item1</code> ✅</p>Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










