对于Javascript中的循环,仅从最后一次迭代输出值
我有这个Javascript代码,按预期工作:
setTimeout(function(){$(".test").append("test1")},1000); setTimeout(function(){$(".test").append("test2")},2000);
它首先显示“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”。 有人知道如何解决这个问题吗?
当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); }
编辑:使用的函数args。
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; }
在这种情况下,变量i
将始终引用i
的当前值(不是调用时的i
的值)。
这就是范围在JavaScript中的作用。
请参阅@Esailija的答案以获得解决方案。
保持i
在范围内最明显的方法是在其他答案中解决,但由于你使用jQuery,你有其他选择。
-
使用
$.each
而不是for
循环,这样你就可以在该范围内的任何地方访问i
变量。 -
使用
delay
而不是setTimeout
。 为此,您需要首先触发队列:$(".test").show(0).delay(timeInterval).append("test" + i)
这是因为您没有从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; }