使用 let 或 const 声明循环变量可天然获得块级作用域,避免变量提升和闭包问题;var 声明会导致 i 泄露且所有闭包共享同一变量,而 let/const 每次迭代创建独立绑定。

在 JavaScript 中,使用 let 或 const 声明循环变量,就能天然获得块级作用域,避免变量泄露到全局或函数作用域,这是最直接有效的做法。
用 let/const 替代 var 声明循环变量
var 声明的变量存在变量提升和函数作用域,导致 for 循环中的 i 会“逃逸”到整个函数甚至全局;而 let 和 const 是块级作用域,每次迭代都绑定独立的绑定(binding),不会互相干扰。
- 错误写法(var):i 在循环结束后仍可访问,且所有闭包共享同一个 i
- 正确写法(let):每次循环 i 都是新绑定,setTimeout 中能正确输出 0、1、2...
// ❌ var 导致污染和闭包问题 for (var i = 0; i console.log(i), 100); // 输出 3, 3, 3 } console.log(i); // 3 —— i 泄露到外层 // ✅ let 自动创建块级作用域 for (let i = 0; i console.log(i), 100); // 输出 0, 1, 2 } console.log(i); // ReferenceError: i is not defined
for...of / for...in 循环天然支持块级作用域
这类循环语法本身基于迭代器,配合 let 使用时逻辑更清晰,变量生命周期严格限制在每次迭代块内。
- 推荐用
for (let item of array)替代传统 for 循环,语义明确、不易出错 - 避免在循环体内重复声明同名变量(即使用 let,也建议保持单一声明)
注意 IIFE 不再是必需方案
ES6 之前常用立即执行函数(IIFE)包裹循环体来“隔离”变量,现在已过时:
- IIFE 写法冗长:
(function(i) { ... })(i) - let 已解决根本问题,无需额外封装
- 仅在需兼容极老环境(如 IE8)时才考虑回退方案
箭头函数 + 块级作用域组合防误用
在事件监听、定时器、Promise 回调等异步场景中,只要循环变量用 let 声明,内部箭头函数就能安全捕获当前轮次的值。
- 不要在循环内用 var 声明同名变量覆盖 let 变量
- 避免解构赋值时意外使用 var(如
for (let [k, v] of map) { var k = ... }) - const 适用于不重赋值的场景(如遍历对象 key),也能享受块级作用域
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











