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

使用for循环与setTimeout显示姓名时出现undefined及i值异常的问题

问题原因与修复方案

问题原因

你遇到的问题根源是变量作用域和闭包的延迟绑定:

  • 用var声明的变量i属于函数级作用域,整个members函数里只有一个i的引用。
  • setTimeout的回调是异步执行的,3秒后才会触发,但此时for循环已经完全跑完,i的值已经变成了4(循环条件是i < arr.length,当i等于4时停止循环)。
  • 回调执行时访问的i是最终的4,而arr[4]不存在,所以返回undefined。

修复方法

方法1:使用let声明循环变量(ES6+推荐)

let会创建块级作用域,每次循环都会生成独立的i变量,回调会绑定当前循环的i值:

function members() {
  var arr = ["Joseph","John","Kumar","Shiva"];
  for(let i = 0; i < arr.length; i++) {
    setTimeout(function() {
      console.log("Member = " + i + ". " + arr[i]);
      document.getElementById("Names").innerHTML = "Member = " + i + ". " + arr[i];
    }, 3000);
  }
}
members();

注:这样所有回调会在3秒后同时执行,最终只会显示最后一个成员。如果想每隔3秒依次显示一个,把延迟时间改成3000 * (i + 1)即可。

方法2:用立即执行函数(IIFE)创建独立作用域

在外层包裹立即执行函数,把当前i作为参数传递进去,保存当前循环的变量值:

function members() {
  var arr = ["Joseph","John","Kumar","Shiva"];
  var i;
  for(i = 0; i < arr.length; i++) {
    (function(currentIndex) {
      setTimeout(function() {
        console.log("Member = " + currentIndex + ". " + arr[currentIndex]);
        document.getElementById("Names").innerHTML = "Member = " + currentIndex + ". " + arr[currentIndex];
      }, 3000);
    })(i);
  }
}
members();

方法3:使用forEach遍历数组

forEach的回调本身自带独立作用域,每次遍历的索引和元素都是当前循环的有效值:

function members() {
  var arr = ["Joseph","John","Kumar","Shiva"];
  arr.forEach(function(member, index) {
    setTimeout(function() {
      console.log("Member = " + (index + 1) + ". " + member);
      document.getElementById("Names").innerHTML = "Member = " + (index + 1) + ". " + member;
    }, 3000);
  });
}
members();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 14:05:20