Javascript:循环的结束?

Javascript:循环的结束?,javascript,closures,anonymous-function,Javascript,Closures,Anonymous Function,我想做以下几点: for (var i = 0; i < 10; ++i) { createButton(x, y, function() { alert("button " + i + " pressed"); } } for(变量i=0;i

我想做以下几点:

for (var i = 0; i < 10; ++i) {
    createButton(x, y, function() { alert("button " + i + " pressed"); }
}
for(变量i=0;i<10;++i){
createButton(x,y,function(){alert(“按钮”+i+“按下”);}
}
问题是我总是得到
I
的最终值,因为Javascript的闭包不是按值来的。

那么如何使用javascript实现这一点呢?

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

for(var dontUse = 0; dontUse < 10; ++dontUse) {
    (function(i) {
        createButton(x, y, function() { alert("button " + i + " pressed"); }
    })(dontUse);
}
for(变量i=0;i<10;++i){
createButton(x,y,(函数(n)){
返回函数(){
警报(“按下按钮”+n+);
}
}(i) );
}

外部的匿名函数将被自动调用,并在其作用域中创建一个新的闭包
n
,每次调用该函数时,该闭包将获取当时的
i

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

for(var i = 0; i < 10; ++i) {
    createButton(x,y, function(value) { return function() { alert(...); }; }(i));
}
for(变量i=0;i<10;++i){
createButton(x,y,函数(值){return function(){alert(…);};}(i));
}

用于(变量i=0;i<10;i++){
(职能(一){
createButton(函数(){alert(“按钮”+i+“按下”);});
})(i) );
}
请注意,JSLint不喜欢这种模式,它抛出“不要在循环中生成函数”


实时演示:

如果您为使用JavaScript 1.7或更高版本的浏览器编码,一个解决方案是使用
let
关键字:

for(var i = 0; i < 10; ++i) {
    let index = i;
    createButton(x, y, function() { alert("button " + index + " pressed"); }
}
for(变量i=0;i<10;++i){
设指数=i;
createButton(x,y,function(){alert(“按钮”+索引+“按下”);}
}
从MDC文档中心:

let关键字导致该项失败 要使用块创建的变量 级别范围,导致新引用 为的每个迭代创建 for循环。这意味着 为每个变量捕获单独的变量 关闭,解决由 共享环境


查看传统方法的示例(创建另一个闭包).

您可以编辑createButton,允许它传递另一个参数,即i。这样,您可以将i存储在createButton函数中并使用它。可能是1的副本。您可能希望在return语句末尾放置分号,以使代码更具可读性。2.iLife通常用paren包装。我喜欢这个answer比Peter的更干净。如果更多的浏览器支持
let
关键字那就太好了。@McStretch我试图在JSFIDLE中做一个
let
demo,但是我无法让它工作。请看这里:Firefox4抛出了一个错误。@Šime-我刚刚看到这个问题:,它说你必须明确地告诉浏览器(现在才使用Firefox)您正在使用1.7。这里有一个更新的提琴:。相当蹩脚吧?显然不是一个好的解决方案,除非每个人都支持1.7或更高版本,谁知道什么时候会发生。@McStretch我明白了。更新的演示(在Firefox中工作)就在这里:看来我们在很长一段时间内无法使用
let
。即使IE10实现了它,我们也必须等到IE9退出市场(这在2020年之前可能不会发生)。
for(var i = 0; i < 10; ++i) {
    createButton(x,y, function(value) { return function() { alert(...); }; }(i));
}
for(var i = 0; i < 10; i++) {
    (function(i) {
        createButton(function() { alert("button " + i + " pressed"); });
    })(i);
}
for(var i = 0; i < 10; ++i) {
    let index = i;
    createButton(x, y, function() { alert("button " + index + " pressed"); }
}