用 let 声明循环变量可解决异步循环中索引值全为最终值的问题,因其每次迭代创建独立绑定;若需兼容旧环境,可用 iife 或箭头函数闭包捕获当前索引。

在 JavaScript 异步循环中,直接用 var 声明的循环变量(如 i)会导致所有异步回调共享同一个变量引用,最终输出的索引值全是循环结束后的值(比如 5)。根本原因是:异步操作(如 setTimeout、fetch、Promise.then)被推入任务队列时,循环早已执行完毕,而 var 是函数作用域、没有块级绑定。
用 let 替代 var 声明索引
let 在每次循环迭代中都会创建一个新的绑定,每个异步回调捕获的是各自迭代中的独立索引值。这是最简洁、现代的解法:
for (let i = 0; i {
console.log(i); // 0, 1, 2, 3, 4(正确)
}, 100);
}
手动创建闭包(兼容旧环境)
若需支持 ES5 或必须用 var,可借助立即执行函数表达式(IIFE)将当前索引作为参数传入,形成闭包保存值:
for (var i = 0; i {
console.log(index); // 0, 1, 2, 3, 4
}, 100);
})(i);
}
用箭头函数 + 参数传递(更轻量的闭包写法)
不显式写 IIFE,而是把索引作为参数传给一个箭头函数,同样利用函数参数的局部性来“冻结”值:
for (var i = 0; i {
setTimeout(() => {
console.log(index);
}, 100);
})(i);
}
处理 Promise 异步循环(如 fetch)
对 Promise 链或 async/await 循环,仍推荐用 let;若用 var,可在 .then 或 await 后显式绑定索引:
// ✅ 推荐:let + async/await
for (let i = 0; i {
console.log(`第 ${j} 个请求完成`); // ❌ 错误:j 已变
});
// 正确写法:
(function(idx) {
fetch(urls[idx]).then(() => {
console.log(`第 ${idx} 个请求完成`);
});
})(j);
}
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











