2012-12-24 50 views
-2

可能重复:
Closures in a for loop and lexical environment使用闭包变量

我学习闭包在JavaScript中......只见例如简单的代码:

for (var i = 0; i < 10; i++) { 
    document.getElementById('box' + i).onclick = function() { 
    alert('You clicked on box #' + i); 
    }; 
} 

但是究竟发生了什么,无论你选择什么div你都会得到一个al关于最后一个i - 最后一次迭代。

我看到内部函数的解决方案,但为什么会发生这种情况?是否在每次迭代中都没有约束onclick事件?

+0

搜索'[javascript]回调循环最后值'。不缺重复。 – 2012-12-24 05:31:00

+0

-1因为,既然你知道*关于闭包,这将很容易找到重复的。尝试使用搜索功能或在创建帖子时查看“类似问题”。 – 2012-12-24 05:33:24

回答

1

每次迭代都会创建一个新函数,但每个函数都参考相同的变量i(内存中的位置)。 i的值仅在处理程序执行时进行评估。在for循环结束之后的那一刻,i的值为10

Wikipedia's article about closures值得一读,并提到闭包可以工作的两种方式:通过绑定变量的当前值或引用变量本身。后者就是JavaScript的情况。

+0

最后一段在上下文中略有误导。例如,在Scala和C#中,闭包也“绑定到变量的引用”。区别在于[特定]变量的范围。 – 2012-12-24 06:05:24

+0

嗯,我可能过于简单了一点,但我认为它有助于理解差异,不是吗? –

+0

我并不是说这是不正确的 - 答案仍然是我的最高票数。对于未来的读者来说,这只是一个记录。 – 2012-12-24 06:13:48

0

良好的旧同变量问题。 - JavaScript的唯一具有的功能范围

for(var i = 0; i < 10; i++) { 
    (function(i) { 
     document.getElementById('box' + i).onclick = function() { 
      alert('You clicked on box #' + i); 
     }; 
    })(i); 
} 

之所以这样,是必要的工作原理是,i通常总是相同的:您可以轻松地将其通过取i作为参数自调用函数绕过它。通过使用以i作为参数的自我调用函数,您每次都会创建一个新的i,然后将其保存在回调函数的闭包中。

+0

我会*爱*看到谁downvoted这个评论。 – ThiefMaster