对于Javascript中的循环仅从最后一次迭代输出值

时间:2012-10-25 21:47:28

标签: javascript jquery for-loop settimeout

我有这个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”。有人知道如何解决这个问题吗?

5 个答案:

答案 0 :(得分:5)

i执行函数时,var setTimeout会增加到2,因此只会将i值打印为2,从而生成test2test2

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

DEMO: 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);
}

修改:使用了函数args。

答案 1 :(得分:3)

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;
}

答案 2 :(得分:2)

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

这就是范围在JavaScript中的作用。

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

答案 3 :(得分:0)

这是因为您没有从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;
}

答案 4 :(得分:0)

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

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

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