如何处理Javascript闭包?

如何处理Javascript闭包?,javascript,jquery,function,closures,Javascript,Jquery,Function,Closures,考虑以下JavaScript的小片段: for(var i in map.maps) { buttons.push($("<button>").html(i).click(function() { alert(i); })); } for(map.maps中的变量i) { 按钮。按($(“”).html(i).单击(函数(){alert(i);})); } 它为map.maps对象(它是一个assoc数组)中的每个字段创建一个按钮。我将索引设置为按钮的文本,并将其设置为提

考虑以下JavaScript的小片段:

for(var i in map.maps)
{
    buttons.push($("<button>").html(i).click(function() { alert(i); }));
}
for(map.maps中的变量i)
{
按钮。按($(“”).html(i).单击(函数(){alert(i);}));
}
它为
map.maps
对象(它是一个assoc数组)中的每个字段创建一个按钮。我将索引设置为按钮的文本,并将其设置为提醒索引。显然,我们希望所有的按钮在单击时都会提醒它自己的文本,但是所有的按钮在单击时都会提醒
map.maps
对象中的final索引的文本

我假设这种行为是由JavaScript处理闭包、返回并从创建闭包的闭包中执行函数的简洁方式造成的

我能想象的解决这个问题的唯一方法是将索引设置为button对象上的数据,并从click回调中使用它。我还可以在我的
按钮
对象中模拟
map.maps
索引,并使用
indexOf
单击找到正确的索引,但我更喜欢前者


我在答案中寻找的是确认我是以正确的方式做的,或者是关于我应该如何做的建议。

如果将更改的值作为参数传递给另一个函数,该值将被锁定:

function createButton(name) {
    return $("<button>").html(name).click(function() { alert(name); });
}

for (var i in map.maps) {
    buttons.push(createButton(i));
}
函数createButton(名称){
返回$(“”).html(名称)。单击(函数(){alert(名称);});
}
for(map.maps中的变量i){
按钮。按下(创建按钮(i));
}

接受闭包,不要绕过它们

for(var i in map.maps)
{
    (function(i){
        buttons.push($("<button>").html(i).click(function() { alert(i); }));
    })(i);
}
for(map.maps中的变量i)
{
(职能(一){
按钮。按($(“”).html(i).单击(函数(){alert(i);}));
})(i) );
}
您需要包装使用var i的代码,以便它最终在一个单独的闭包中结束,并且该值保存在该闭包的本地var/param中


使用单独的函数(如lonesomeday的答案中的函数)稍微隐藏了这种闭包行为,但同时更加清晰。

这是完成您尝试的操作的最优雅的方式:

var buttons = myCharts.map(function(chart,i) {
    return $("<button>").html(chart).click(function(event){
        alert(chart);
    });
}
var buttons=myCharts.map(函数(chart,i){
返回$(“”).html(图表)。单击(函数(事件){
警报(图表);
});
}
需要使用闭包来在javascript中优雅地编写代码,而不应该绕过它们。否则,您无法执行嵌套for循环之类的操作(没有可怕的黑客攻击)。当需要闭包时,请使用闭包。不要害怕在函数中定义新函数。

for(map.maps中的var i){
for(var i in map.maps){
    (function(i){
         buttons.push($("<button>").html(i).click(function() { alert(i); }))
    })(i);
}
(职能(一){ 按钮。按($(“”).html(i).单击(函数(){alert(i);})) })(i) ); }
在您的案例中,闭包失败的原因是,即使在绑定函数后,它的值仍会更新,在本例中,它是事件处理程序。这是因为闭包只记住对变量的引用,而不记住绑定变量时的实际值

使用已执行的匿名函数,您可以强制执行正确的值,这是通过将i传递给匿名函数来实现的,因此在匿名函数的范围内,i将被重新定义。

几乎完全复制我的代码的速度(非常轻微)更快,因为函数只创建了一次。但是效果完全相同。