JavaScript变量绑定和循环

ale*_*2k8 28 javascript closures scope loops

考虑这样的循环:

for(var it = 0; it < 2; it++)
{
    setTimeout(function() {
        alert(it);
    }, 1);
}
Run Code Online (Sandbox Code Playgroud)

输出是:

=> 2
=> 2
Run Code Online (Sandbox Code Playgroud)

我希望它是:0,1.我看到两种方法来解决它:

解决方案#1.

这个基于我们可以将数据传递给setTimeout的事实.

for(var it = 0; it < 2; it++)
{
    setTimeout(function(data) {
        alert(data);
    }, 1, it);
}
Run Code Online (Sandbox Code Playgroud)

解决方案#2.

function foo(data)
{
    setTimeout(function() {
        alert(data);
    }, 1);
}

for(var it = 0; it < 2; it++)
{
    foo(it);
}
Run Code Online (Sandbox Code Playgroud)

还有其他选择吗?

Rus*_*Cam 43

实际上并不仅仅是你提出的两种方式,而是另一种方式

for(var it = 0; it < 2; it++)
{
    (function() {
        var m = it;   
        setTimeout(function() {
            alert(m);
        }, 1);
    })(); 
}
Run Code Online (Sandbox Code Playgroud)

实质上,您需要在闭包中捕获变量值.此方法使用立即调用的匿名函数来捕获it局部变量中的外部变量值m.

这是一个可以玩的工作演示.添加/编辑 URL以查看代码

  • +1.但是,您可以通过将方法签名更改为:`function(m){/*code*/})(it)来稍微修改它. (4认同)

tbo*_*son 16

使用let关键字,您可以完全解决这个问题:

for(let it = 0; it < 2; it++)
{
    setTimeout(function() {
        alert(it);
    }, 1);
}
Run Code Online (Sandbox Code Playgroud)

  • @PardeepJain在ES6版本的JS中引入了let关键字. (3认同)