2011-06-06 100 views
6

考虑的JavaScript的这个小片断:如何解决Javascript关闭问题?

for(var i in map.maps) 
{ 
    buttons.push($("<button>").html(i).click(function() { alert(i); })); 
} 

它创建用于每个在map.maps对象中的字段中的一个按钮(这是一个ASSOC数组)。我将索引设置为按钮的文本,并将其设置为提醒索引。很显然,人们会希望所有按钮在单击时都会提醒它自己的文本,但是当单击时,所有按钮都会提醒map.maps对象中最终索引的文本。

我认为这种行为是由整洁的方式引起的,JavaScript处理关闭,返回并从创建它们的闭包执行函数。

我可以想象得到解决这个问题的唯一方法是将索引设置为按钮对象上的数据,并从点击回调中使用它。我也可以模仿我的buttons对象中的map.maps索引,并使用indexOf找到正确的点击索引,但我更喜欢前一种方法。

我在寻找的答案是确认,我正在做它正确的方式,或建议如何我做到这一点。

+1

[我如何将JS变量的值(不是引用)传递给函数]几乎完全重复?(http://stackoverflow.com/questions/2568966/how-do-i-pass-the -value-not-the-reference-of-js-variable-to-a-function) – 2011-06-06 09:04:35

回答

9

拥抱关闭,不解决它们。

for(var i in map.maps) 
{ 
    (function(i){ 
     buttons.push($("<button>").html(i).click(function() { alert(i); })); 
    })(i); 
} 

你需要用一个使用VAR我,以便它在一个单独的封闭结束和值保持在该关闭一个局部变量/参数的代码。

在lonesomeday的回答中使用一个单独的函数隐藏了这个闭包行为,但同时更清晰。

+0

我的代码速度很快,因为函数只创建一次。但是,效果完全相同。 – lonesomeday 2011-06-06 11:23:49

4

如果你通过了变更值的另一个函数作为参数,该值将被锁定在:

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

for (var i in map.maps) { 
    buttons.push(createButton(i)); 
} 
0

这是最优雅的方式做你想做什么:

var buttons = myCharts.map(function(chart,i) { 
    return $("<button>").html(chart).click(function(event){ 
     alert(chart); 
    }); 
} 

需要关闭在JavaScript代码优雅,并且不应该解决它们。否则,你不能做像嵌套for循环(没有可怕的黑客)。当你需要关闭时,使用关闭。不要害怕在函数内部定义新的函数。

1
for(var i in map.maps){ 
    (function(i){ 
     buttons.push($("<button>").html(i).click(function() { alert(i); })) 
    })(i); 
} 

为什么封你的情况失败的原因是,它的功能被绑定后,也这是在这种情况下是事件处理仍在更新值。这是由于闭包只记住对变量的引用,而不是绑定时的实际值。

通过执行匿名函数,您可以执行正确的值,这通过将我传递给匿名函数来实现,因此,然后在匿名函数的范围内我被重新定义。