变量全局范围理解问题

Mar*_* P. 5 javascript variables scope

我的问题实际上是一个理解 - 我有一个有效的解决方案,我只是不明白它是如何工作的.

好的,所以 - 我要做的是在循环中添加一个setTimeout,并通过它传递一个变化的值.例:

for (i=0;i<11;i++)
{
     setTimeout("alert(i)",1000);
}
Run Code Online (Sandbox Code Playgroud)

如果我理解正确,这不起作用,因为Javascript不(像PHP)将i的值传递给函数,但传递i的引用 - 这反过来不是静态的,但继续随计数器更改.

我找到了一个解决方案,如下所示:

for (i=0;i<11;i++)
{
    setTimeout(function(x){return function(){alert(x)};}(i),1000);
}
Run Code Online (Sandbox Code Playgroud)

我真的不明白这实际上是做什么的.看起来它将"警报"功能传递回调用函数,但我无法理解.

我可以使用这个解决方案,并将其适应其他环境,但我真的很想了解我的所有代码,而不仅仅是使用我在某处找到的东西,并且很高兴它的工作原理.此外,我正在寻找一个更纤薄的版本来实现同样的目标.

谢谢,马可

use*_*716 2

您调用返回函数的函数的原因是您需要通过某种方式让传递给的函数拥有对 的当前值的setTimeout()引用。i

由于代码等待运行 1000 毫秒,因此for循环将在运行之前完成,并且 if 的值为i11。

但由于函数有自己的变量作用域,因此可以将 的值传递i给立即调用的函数,这样它就被局部变量 引用,而被返回的函数在finally 调用它x时可以引用它。setTimeout()

for (i=0; i<11; i++) {
    setTimeout(function(x){
                 // CONTINUE HERE:
                 // x is a local variable to the function being executed
                 //    which references the current value of i

                 // A function is being returned to the setTimeout that
                 //    references the local x variable
                 return function(){ alert(x); };

               }(i) // START HERE:
                    // The "outer" function is executed immediately, passing the
                    //   current value of "i" as the argument.
     ,1000);
}
Run Code Online (Sandbox Code Playgroud)

所以你最终会得到一个等价的东西,如下所示:

setTimeout( function(){ alert(x); }, 1000); //...where x === 0
setTimeout( function(){ alert(x); }, 1000); //...where x === 1
setTimeout( function(){ alert(x); }, 1000); //...where x === 2
setTimeout( function(){ alert(x); }, 1000); //...where x === 3
// etc.
Run Code Online (Sandbox Code Playgroud)