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

如何在使用var时修复for循环中setTimeout的索引输出异常

解决var在for循环异步回调中索引异常的问题

因为var声明的变量属于函数作用域,整个init函数内只有一个index变量。setTimeout的回调是异步执行的,当所有回调触发时,for循环已经执行完毕,index的值已经变为5,所以所有回调都会打印5。

以下是几种不使用let的解决方案:

  • 使用立即执行函数表达式(IIFE)创建独立作用域

    function init() {
      for (var index = 0; index < 5; ++index) {
        (function(currentIndex) {
          setTimeout(() => {
            console.log(currentIndex);
          }, index);
        })(index);
      }
    }
    

    每次循环时,通过IIFE将当前index的值传入,形成独立作用域,currentIndex会保留当前循环的索引值,回调访问的是该作用域内的变量。

  • 给setTimeout传递额外参数

    function init() {
      for (var index = 0; index < 5; ++index) {
        setTimeout((currentIndex) => {
          console.log(currentIndex);
        }, index, index);
      }
    }
    

    setTimeout的第三个及后续参数会作为回调函数的参数传递,这样每个回调都会拿到当前循环的index值。

  • 利用bind绑定参数

    function init() {
      for (var index = 0; index < 5; ++index) {
        setTimeout(console.log.bind(console, index), index);
      }
    }
    

    通过bind方法给console.log绑定当前的index作为第一个参数,每个setTimeout的回调都是绑定了不同参数的函数,执行时会打印对应索引。

  • 使用Function构造函数(不推荐)

    function init() {
      for (var index = 0; index < 5; ++index) {
        setTimeout(new Function('console.log(' + index + ');'), index);
      }
    }
    

    每次循环生成一个新函数,函数内部的索引是字符串拼接后的字面量值,会保留当前循环的索引。但这种方式可读性差,存在安全风险,不建议使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 07:55:20