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

为何使用var时循环输出11,而let可实现正常遍历输出?

为什么用var声明循环变量会全输出11,用let却能正常输出0到10?

先看你给出的这段代码:

var functions = []; 
for (var x = 0; x <= 10; x++) { 
  functions.push(function() { console.log(x); }); 
} 
functions.forEach( function(func) { func(); } ); 

用var时的核心问题:共享同一个变量引用

用var声明的x是函数级作用域(如果这段代码不在函数内部,那就是全局作用域),整个循环过程中只有这一个x变量存在。你每次往数组里添加的函数,并没有“保存”当前循环的x值,而是记住了x这个变量本身的引用。

等循环结束时,x已经自增到11了(最后一次循环x=10满足条件,执行完循环体后x++变成11,此时不满足x<=10,循环停止)。当你后续调用数组里的函数时,它们都会去取这个已经变成11的x,所以自然全输出11。

用let时的关键差异:每次循环创建独立变量

let是块级作用域,而且在for循环里有个特殊的设计:每一轮循环迭代时,都会创建一个全新的x变量,这个变量只属于当前这一轮循环的块作用域。

也就是说,你每一次添加到数组里的函数,引用的都是当前循环独有的那个x,它的值就是当前迭代的数值(0、1、2...10)。等循环结束后,每个函数各自持有自己那一轮的x引用,调用时就会依次输出0到10。

额外补充:用var模拟let的效果

如果想用var实现和let一样的结果,可以手动用立即执行函数(IIFE)创建独立作用域:

var functions = []; 
for (var x = 0; x <= 10; x++) { 
  (function(currentX) {
    functions.push(function() { console.log(currentX); }); 
  })(x);
} 
functions.forEach( function(func) { func(); } ); 

这里每次循环都把当前的x值传给立即执行函数的参数currentX,这个currentX是函数内部的局部变量,每个数组里的函数都引用着自己对应的currentX,所以也能正常输出0到10。而let相当于帮你自动完成了这个“创建独立变量”的工作,不用手动写IIFE了。

内容的提问来源于stack exchange,提问作者Rene Israel Ibarra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:31:14