[英]Passing functions to setTimeout in a loop: always the last value?
我正在尝试使用setTimeout执行一个匿名函数,该函数会将信息传递给我,但是遇到了麻烦。 这个(硬编码版本)可以正常工作:
setTimeout(function(){alert("hello");},1000);
setTimeout(function(){alert("world");},2000);
但是我试图从数组中获取hello和world并将其传递给函数,而无需(a)使用全局变量,以及(2)使用eval。 我知道如何使用globals或eval做到这一点,但是如果没有我怎么做。 这是我想做的(但我知道这将无法工作):
var strings = [ "hello", "world" ];
var delay = 1000;
for(var i=0;i<strings.length;i++) {
setTimeout( function(){alert(strings[i]);}, delay);
delay += 1000;
}
当然,字符串[i]将脱离上下文。 如何在没有eval或globals的情况下将字符串[i]传递给该匿名函数?
这是经常重复出现的“如何在闭包中使用循环变量”问题。
规范的解决方案是调用一个函数,该函数返回绑定到循环变量当前值的函数:
var strings = [ "hello", "world" ];
var delay = 1000;
for(var i=0;i<strings.length;i++) {
setTimeout(
(function(s) {
return function() {
alert(s);
}
})(strings[i]), delay);
delay += 1000;
}
外部定义function(s) { ... }
创建一个新的作用域,其中s
绑定到所提供参数的当前值-即strings[i]
- 内部作用域可用。
只需在setTimeout调用周围添加一个范围:
var strings = [ "hello", "world" ];
var delay = 1000;
for(var i=0;i<strings.length;i++) {
(function(s){
setTimeout( function(){alert(s);}, delay);
})(strings[i]);
delay += 1000;
}
您可以编写一个单独的函数来设置超时:
function doTimer(str, delay) {
setTimeout(function() { alert(str); }, delay);
}
然后从循环中调用它:
var delay = 1000;
for(var i=0;i<strings.length;i++) {
doTimer(strings[i], delay);
delay += 1000;
}
var strings = [ "hello", "world" ];
var delay = 1000;
for(var i=0;i<strings.length;i++) {
setTimeout( new Function('alert(strings[i]);'), delay);
delay += 1000;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.