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

在for循环中嵌套setTimeout返回undefined的技术求助

Why Your setTimeout in for Loop Isn't Working as Expected

Hey there! Let's break down why your code is outputting undefined three times, and walk through several fixes to get it working right.

The Root Cause

The issue stems from two key JavaScript behaviors:

  • Variables declared with var have function-level scope, not block scope. That means every iteration of your loop shares the exact same i variable.
  • setTimeout runs its callback asynchronously—by the time the 500ms delay is up, your entire loop has already finished. The value of i is now 3 (since the loop stops when i < 3 is false), and listItems[3] doesn't exist—hence the undefined output.

Your second attempt added an i parameter to the setTimeout callback, but that doesn't work because setTimeout passes the timer's unique ID as the first argument to the callback, not your loop's i value. You're still referencing the shared i variable from the loop.

Fixes to Try

1. Use let Instead of var (ES6+)

let creates block-scoped variables, so each loop iteration gets its own copy of i. The setTimeout callback captures the i value from the specific iteration it was created in:

var listItems = ['1','2','3'];
for(let i = 0 ; i < listItems.length ; i++){
    setTimeout(function(){ console.log(listItems[i]) },500)
}

2. Create a Closure with an IIFE

If you need to support older environments without ES6, use an Immediately Invoked Function Expression (IIFE) to create a separate scope for each iteration, preserving the current i value:

var listItems = ['1','2','3'];
for(var i = 0 ; i < listItems.length ; i++){
    // Wrap setTimeout in an IIFE to capture the current loop index
    (function(currentIndex) {
        setTimeout(function(){ console.log(listItems[currentIndex]) },500)
    })(i);
}

3. Use Array.forEach()

The forEach method iterates over each element and creates a unique scope for its callback, eliminating shared variable issues entirely:

var listItems = ['1','2','3'];
listItems.forEach(function(item) {
    setTimeout(function(){ console.log(item) },500)
});

4. Pass Extra Arguments to setTimeout

setTimeout accepts additional arguments that get passed directly to the callback. Use this to pass the current index:

var listItems = ['1','2','3'];
for(var i = 0 ; i < listItems.length ; i++){
    // Pass the current index as the third argument to setTimeout
    setTimeout(function(index){ console.log(listItems[index]) },500, i)
}

All these approaches will make your code output 1, 2, 3 (after 500ms) instead of undefined three times.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:27:22