【问题标题】:Using closures in loop- scope variable [duplicate]在循环范围变量中使用闭包
【发布时间】:2012-12-24 05:03:08
【问题描述】:

可能重复:
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,您都会收到关于最后一个i - 最后一个迭代的警报。

我看到了内部函数问题的解决方案,但为什么会发生这种情况?不是每次迭代都绑定onclick 事件吗?

【问题讨论】:

  • 搜索[javascript] callback loop last value。不乏重复。
  • -1 因为你知道关于闭包,这很容易找到重复项。尝试使用搜索功能或在创建帖子时查看“类似问题”。

标签: javascript closures


【解决方案1】:

每次迭代都会创建一个新函数,但每个函数都引用相同变量i(内存中的一个位置)。 i 的值仅在执行处理程序时进行评估。那一刻是在for 循环完成之后很久,当时i 的值是10

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

【讨论】:

  • 最后一段在上下文中有点误导。例如,在 Scala 和 C# 中,闭包也“绑定对变量的引用”。区别在于 [特定] 变量的范围。
  • 嗯,我可能有点过于简单了,但我认为这有助于理解差异,不是吗?
  • 我并不是说它不正确 - 答案仍然有我的赞成票。这只是给未来读者的一个注释/nit。
【解决方案2】:

好旧的同变量问题。您可以通过将i 作为参数的自调用函数传递它来轻松绕过它:

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

这是必要且有效的原因是 i 通常总是相同的 - JavaScript 只有一个函数范围。通过使用以i 作为参数的自调用函数,您每次都会创建一个新的i,然后将其保存在回调函数的闭包中。

【讨论】:

  • 我希望 喜欢 看到投反对票的人的评论。
猜你喜欢
  • 1970-01-01
  • 2013-08-30
  • 1970-01-01
  • 2014-05-19
  • 2011-11-12
  • 1970-01-01
  • 1970-01-01
  • 2018-08-05
相关资源
最近更新 更多