Javascript:关闭循环?

时间:2011-04-05 16:51:58

标签: javascript closures anonymous-function

我想做以下事情:

for (var i = 0; i < 10; ++i) {
    createButton(x, y, function() { alert("button " + i + " pressed"); }
}

这个问题是我总是得到i的最终值,因为Javascript的闭包不是按值。
那么我怎么能用javascript做到这一点?

5 个答案:

答案 0 :(得分:7)

如果您要编写使用JavaScript 1.7或更高版本的浏览器,则可以使用let关键字来解决一个问题:

for(var i = 0; i < 10; ++i) {
    let index = i;
    createButton(x, y, function() { alert("button " + index + " pressed"); }
}

来自MDC文档中心:

  

let关键字会导致该项目   用块创建的变量   级别范围,导致新的引用   为每次迭代创建   for循环。这意味着一个   为每个捕获单独的变量   关闭,解决由此引起的问题   共享环境。

查看传统方法的MDC Doc Center(创建另一个闭包)。

答案 1 :(得分:6)

for(var i = 0; i < 10; i++) {
    (function(i) {
        createButton(function() { alert("button " + i + " pressed"); });
    })(i);
}

请注意,JSLint不喜欢这种模式。它抛出“不要在循环中创建函数。”。

现场演示: http://jsfiddle.net/simevidas/ZKeXX/

答案 2 :(得分:4)

通过执行另一个函数为闭包创建一个新的作用域:

for(var i = 0; i < 10; ++i) {
    createButton(x,y, function(value) { return function() { alert(...); }; }(i));
}

http://www.mennovanslooten.nl/blog/post/62

答案 3 :(得分:1)

您需要将闭包放入单独的函数中。

for(var dontUse = 0; dontUse < 10; ++dontUse) {
    (function(i) {
        createButton(x, y, function() { alert("button " + i + " pressed"); }
    })(dontUse);
}

Thise代码创建一个匿名函数,该函数将i作为循环每次迭代的参数。
由于此匿名函数对每次迭代都有一个单独的i参数,因此它解决了问题。

这相当于

function createIndexedButton(i) {
    createButton(x, y, function() { alert("button " + i + " pressed"); }
}

for(var i = 0; i < 10; ++i) {
    createIndexedButton(i);
}

答案 4 :(得分:0)

for(var i = 0; i < 10; ++i) {
    createButton(x, y, (function(n) {
        return function() {
            alert("button " + n + " pressed");
        }
    }(i));
}

外部的匿名函数会自动调用,并在其范围内创建一个n的新闭包,每当它出现{em>然后当前值为i时调用