如何将变量传递给setTimeout函数?

Cap*_*ack 5 javascript

我正在尝试设置五个交错的函数调用(相隔一秒发生).那部分工作正常.什么行不通,我不能将值0到4传递给回调函数.它每次只传递'5'.我似乎无法弄清楚为什么以及如何解决它.

码:

?function callback(num)
{
    console.log(num);
}

for (var i = 0, loadDelay = 1000; i < 5; ++ i, loadDelay += 1000)
    setTimeout(function() { callback(i); }, loadDelay);
Run Code Online (Sandbox Code Playgroud)

结果:

5
5
5
5
5
Run Code Online (Sandbox Code Playgroud)

期望的结果:

0
1
2
3
4
Run Code Online (Sandbox Code Playgroud)

ZER*_*ER0 12

那是因为你创建了一个闭包.所以你传递的功能是setTimeout共享相同的i实例.在支持标准(不是IE)的浏览器中,您可以:

setTimeout(callback, loadDelay, i);
Run Code Online (Sandbox Code Playgroud)

请参阅:http: //www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#timers

否则你必须实际上bind是函数的参数:

setTimeout(callback.bind(undefined, i), loadDelay);
Run Code Online (Sandbox Code Playgroud)

请参阅:https: //developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind

如果浏览器不支持ES5 bind方法,您可以实现上面链接中存在的填充程序,也可以手动执行以下操作:

setTimeout(function(index){
    return function() { callback(index) }
}(i), loadDelay);
Run Code Online (Sandbox Code Playgroud)

但我会说它更具可读性bind,值得实现垫片.你可以实际使用它:https://github.com/kriskowal/es5-shim

在本地不支持es5的浏览器中添加es5功能(尽可能).


Jar*_*Par 6

Use a lambda / function expression to capture the current value. For example

for (var i = 0, loadDelay = 1000; i < 5; ++ i, loadDelay += 1000) {
  var doCall = function (j) {
    setTimeout(function() { callback(j); }, loadDelay);
  }
  doCall(i);
}
Run Code Online (Sandbox Code Playgroud)

The problem here is that there is only 1 i value for all iterations of the loop. Variables in javascript have function scope even though you can declare them inside of a block. This means i is alive for the entire function.

To illustrate the problem consider the below code executes exactly the same as your sample

var i;
for (i = 0, loadDelay = 1000; i < 5; ++ i, loadDelay += 1000) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

My solution works because it introduces a new function and hence a new variable lifetime for j. This saves the current value of i in the function for use in the setTimeout callback