在javascript闭包中重新定义局部变量

时间:2011-01-19 15:56:12

标签: javascript closures

我的代码如下:

for( var i=0; i<10; i++ ) {
   var someClickableObject = new Object();
   someClickableObject.index = i; 

   eventListenerFunction(someClickableObject, 'click', function() {
      alert(someClickableObject.index);
   });
}

所以我创建了一堆可点击的对象,给每个属性等于循环索引,在对象上设置一个click事件来警告其索引属性。

我希望每个对象都警告创建它的索引i。相反, all 对象提醒9.我认为这是因为事件监听器在对象上形成一个闭包,在每次迭代时重新定义。

关于如何解决这个问题的任何想法?

1 个答案:

答案 0 :(得分:1)

问题实际上与您所写的内容相反:所有这些函数共享相同的闭包。 (编辑 - 在重新阅读你写的内容之后,我不确定它与任何东西“相反”;重点是你传递给“eventListenerFunction”的所有那些小函数都将共享相同的内容变量,“someClickableObject”,所以在循环结束时,它们都将引用在最后一次迭代中创建的那个!)

要修复它,你需要以某种方式引入另一个范围:

eventListenerFunction(someClickableObject, 'click', (function(obj) {
  return function() {
    alert(obj.index);
  };
})(someClickableObject));

这引入了一个匿名函数。通过引用局部变量调用该小函数,该函数具有创建另一个范围的效果。该函数返回实际传递给该“eventListener”事物的函数。它现在有了自己的“someClickableObject”副本。

然而,它只是一个副本。在你的情况下,这没关系,因为你在每次迭代时都在创建一个新对象。在实践中,我几乎从不担心这种情况;通常我需要担心的是浅拷贝(因为它通常只是一个计数器,或一个字符串值的密钥,或类似的东西)。

相关问题