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

JS for循环输出异常:为什么执行后五次都打印500而非100到500?

问题原因分析

这一问题是var声明的作用域特性与闭包的变量捕获逻辑共同导致的:

  • 你代码中使用var声明的变量不存在块级作用域,只有全局/函数级作用域,因此循环中每次赋值的myindex都是同一个全局变量,不会每次循环生成独立的新变量。
  • 你推入数组的箭头函数属于闭包,它捕获的是myindex变量的引用而非循环执行时的瞬时值。
    当第一轮循环全部执行完毕后,全局的myindex已经被赋值为5,此时再执行数组中存储的所有闭包函数,读取到的myindex都是已经更新到5的值,因此最终输出5次my number is:500。
常用修复方案

方案1:使用let声明块级变量

let具备块级作用域,每次循环会生成独立的myindex变量,闭包会捕获对应循环的独立变量,即可得到预期输出:

const calculatenumbers = [];
for (var i = 1; i <= 5; i++) {
  let myindex = i;
  calculatenumbers.push(() => {
    var calculatednumber = myindex * 100;
    console.log('my number is:' + calculatednumber);
  });
}

for (var j = 0 ; j < calculatenumbers.length; j++) {
  calculatenumbers[j]();
}

你也可以直接在for循环头部用let声明i,JS会自动为每次循环生成独立的i变量,无需额外声明myindex:

const calculatenumbers = [];
for (let i = 1; i <= 5; i++) {
  calculatenumbers.push(() => {
    var calculatednumber = i * 100;
    console.log('my number is:' + calculatednumber);
  });
}

for (var j = 0 ; j < calculatenumbers.length; j++) {
  calculatenumbers[j]();
}

方案2:使用立即执行函数(IIFE)锁定变量值

这是ES6推出let之前的传统解决方案,利用函数作用域锁定每次循环的瞬时值:

const calculatenumbers = [];
for (var i = 1; i <= 5; i++) {
  (function(myindex) {
    calculatenumbers.push(() => {
      var calculatednumber = myindex * 100;
      console.log('my number is:' + calculatednumber);
    });
  })(i)
}

for (var j = 0 ; j < calculatenumbers.length; j++) {
  calculatenumbers[j]();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 23:54:00