【问题标题】:For Loop in Javascript outputs value only from last iterationJavascript 中的 For 循环仅输出上次迭代的值
【发布时间】:2012-10-16 04:22:11
【问题描述】:

我有这个 Javascript 代码,它按预期工作:

<div class="test"></div>

<script>
setTimeout(function(){$(".test").append("test1")},1000);
setTimeout(function(){$(".test").append("test2")},2000);
</script>
<script src="js/jquery.min.js"></script>

它首先显示“test1”,然后一秒钟后显示“test2”,例如:“test1test2”,这就是我想要的。

当我尝试在 FOR 循环中执行此操作时,如下所示:

var timeInterval = 1000;
for (var i = 0, l = 2; i < l; i++ ) {
    setTimeout(function(){$(".test").append("test" + i)},timeInterval);
    timeInterval += 1000;
}

然后我先得到“test2”,然后一秒钟后得到“test2”,例如:“test2test2”,这不是我想要的。

事实上,如果 l = 3,那么我得到的是“test3test3test3”而不是“test1test2test3”。有人知道如何解决这个问题吗?

【问题讨论】:

  • 我认为因为超时时间比它通过 i 的速度要长,所以当它评估 i 时它已经是 3

标签: javascript jquery for-loop settimeout


【解决方案1】:

setTimeout 正在执行函数时,var i 递增到 2,因此它只是将 i 值打印为 2,从而得到 test2test2

您应该使用闭包来使用i 的实例,它将打印test1test

演示: http://jsfiddle.net/mBBJn/1/

var timeInterval = 1000;
for (var i = 0, l = 2; i < l; i++) {
    (function(i) {
        setTimeout(function() {
            $(".test").append("test" + (i+1))
        }, timeInterval);
        timeInterval += 1000;
    })(i);
}

编辑:使用了函数参数。

【讨论】:

    【解决方案2】:

    for 循环不会创建新的作用域,你可以使用另一个函数来做:

    var timeInterval = 1000;
    for (var i = 0, l = 2; i < l; i++) {
        setTimeout((function(i) {
            return function() {
                $(".test").append("test" + i);
            }
        })(i), timeInterval);
        timeInterval += 1000;
    }
    

    【讨论】:

      【解决方案3】:

      在这种情况下,变量i 将始终引用i 的当前值(而不是调用时i 的值)。

      这就是 JavaScript 中作用域的工作原理。

      请参阅@Esailija 的答案以获取解决方案。

      【讨论】:

        【解决方案4】:

        i 保持在范围内的最明显方法已在其他答案中得到解决,但由于您使用的是 jQuery,因此您还有其他选择。

        1. 使用$.each 而不是for 循环,这样您就可以在该范围内的任何位置访问i 变量。

        2. 使用delay 而不是setTimeout。为此,您需要先触发队列:$(".test").show(0).delay(timeInterval).append("test" + i)

        【讨论】:

          【解决方案5】:

          这是因为您没有从 for 循环中捕获 i 的值。你可以调整你的代码使其工作:

          var timeInterval = 1000;
          for (var i = 0, l = 2; i < l; i++ ) {
              (function(i2, timeInterval2) {
                  setTimeout(function() {
                      $(".test").append("test" + i2);
                  }, timeInterval2);
              })(i, timeInterval);
              timeInterval += 1000;
          }
          

          【讨论】:

          • 感谢科里的建议。您需要从以下位置删除右括号之一:timeInterval));到时间间隔);它有效。
          猜你喜欢
          • 2016-05-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多