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

JavaScript for循环中var替代let为何返回undefined

为什么for循环中用var代替let会返回undefined

核心原因是var和let的作用域规则差异,结合setTimeout的异步执行特性共同导致。

运行逻辑拆解

首先明确基础前提:setTimeout的回调是异步宏任务,不会在循环执行时立刻运行,会等所有同步代码(也就是整个for循环)执行完毕、调用栈清空后,才会等到定时触发执行回调。

let声明循环变量的场景

const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

for (let i = 0; i < 10; i++) {
  setTimeout(() => console.log(a[i]), 3000);
}

运行结果:3秒后依次输出1,2,3,4,5,6,7,8,9,10

  • 原理:let遵循块级作用域规则,for循环的每一次迭代都会生成一个独立的i变量绑定,每个setTimeout回调捕获的都是当前迭代专属的i值。等回调执行时,拿到的就是对应轮次的0-9索引,访问数组元素自然返回正确结果。

var声明循环变量的场景

var i = 0;
for (i = 0; i < 10; i++) {
  setTimeout(() => console.log(a[i]), 3000);
}

运行结果:3秒后输出10个undefined

  • 原理:var没有块级作用域,无论在循环内还是循环外声明,整个运行环境中只有一个全局共享的i变量。for循环同步执行的速度远快于3秒定时,等回调开始执行时,循环早就跑完了,此时共享的i值已经累加到10(循环终止条件是i < 10,最后一次i++后i变为10才跳出循环)。而数组a的有效索引范围是0-9,访问a[10]这个不存在的索引就会返回undefined,10个回调都访问同一个i=10,自然全输出undefined。

补充:如果要在var的写法下拿到正确结果,可以借助闭包或者给setTimeout传第三个参数固定每次的i值,比如:

for (var i = 0; i < 10; i++) {
  setTimeout((val) => console.log(a[val]), 3000, i);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 09:06:19