You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript for循环中使用let和var声明迭代变量有什么区别?

JavaScript for循环中let与var声明迭代变量的差异说明

二者运行逻辑存在明显差异,核心原因是作用域规则不同

  • var关键字的作用域是函数级/全局级,没有块级作用域的概念。用var声明的迭代变量会被提升到当前函数或全局作用域,整个循环全程只复用同一个变量,每次迭代只是修改这个变量的值。
    最典型的验证案例:
    for (var i = 0; i < 3; i++) {
      setTimeout(() => console.log(i), 0)
    }
    // 最终会连续输出3次3
    
    这是因为异步的定时器执行时,循环已经运行结束,全局/函数作用域里的i已经被更新为3了。
  • let关键字支持块级作用域,且for循环头部用let声明变量是JS的特殊规则:每次迭代都会创建一个独立的、仅属于当前迭代块的变量,不同迭代的变量互不干扰。
    同样的案例换成let结果完全不同:
    for (let i = 0; i < 3; i++) {
      setTimeout(() => console.log(i), 0)
    }
    // 会依次输出0、1、2
    
    每个定时器拿到的都是当前迭代的独立i变量,所以不会出现值被覆盖的问题。

底层运行逻辑不相同

  • var声明的迭代变量:仅在循环初始化阶段创建1次,存储在当前函数的变量环境或者全局环境中,全程复用。
  • let声明的迭代变量:初始化阶段创建初始值后,每次迭代都会新生成一个同名变量,用上一次迭代的结果赋值,每个变量单独存储在当前迭代的块级词法环境中。

性能差异可以忽略

目前Chrome的V8、Firefox的SpiderMonkey等主流JS引擎都对let的块级作用域做了高度优化,二者性能几乎没有区别。极端场景下var因为不需要创建多个块级变量,会有微乎其微的性能优势,但这个优势完全抵不上var可能带来的作用域污染、逻辑bug风险,实际开发优先选let即可。

该差异不适用于while、do-while循环

for循环头部的let迭代变量每次迭代创建新实例是JS专门为for循环做的特殊处理,while/do-while没有这个规则:不管用let还是var声明迭代变量,整个循环全程都只会有一个变量,不存在每次迭代新建的逻辑。
验证案例:

let i = 0;
while (i < 3) {
  setTimeout(() => console.log(i), 0)
  i++
}
// 最终还是输出3次3,和用var的效果一致

内容的提问来源于stack exchange,提问作者Vahe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 14:36:05