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

for循环中var与let的差异解析:为何var示例中i最终为4?

为什么用var的循环里setTimeout会拿到i=4?

先看两种代码的执行结果:

用let声明循环变量时:

const array = [1, 2, 3, 4];

for (let i = 0; i < array.length; i++) {
  setTimeout(() => {
    console.log(array[i]);
  }, 1000);
}

1秒后会依次输出1, 2, 3, 4。

换成var声明循环变量时:

const array = [1, 2, 3, 4];

for (var i = 0; i < array.length; i++) {
  setTimeout(() => {
    console.log(array[i]);
  }, 1000);
}

1秒后会输出四次undefined。

核心原因:var的作用域与异步执行的冲突

  • var声明的变量属于函数作用域(如果不在函数内就是全局作用域),整个for循环里的i是同一个变量——循环的每一次迭代都是在修改这个变量的值,从0一直自增到4。
  • setTimeout是异步任务,它的回调函数不会立刻执行,要等1秒后才会被加入执行队列。而这时候for循环早就跑完了:当i自增到4时,i < array.length(也就是4<4)的条件不成立,循环终止,此时i的固定值就是4。
  • 等四个setTimeout的回调依次执行时,它们访问的都是同一个全局的i,这时候i=4,而数组array的索引最大是3,array[4]不存在,所以输出undefined。

对比let的情况:let是块级作用域,循环的每一次迭代都会创建一个全新的i变量,每个setTimeout的回调捕获的都是当前迭代对应的那个i,所以1秒后能正确输出数组的对应元素。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 06:35:18