为什么一个JavaScript闭包可以工作而另一个不能';T

为什么一个JavaScript闭包可以工作而另一个不能';T,javascript,scope,closures,Javascript,Scope,Closures,有两个版本,假设当用户单击第一个链接时,它将发出警报“1”,第二个链接“2”,以此类推: 第1版: <a href="#" id="link1">click me</a> <a href="#" id="link2">click me</a> <a href="#" id="link3">click me</a> <a href="#" id="link4">click me</a> <a hr

有两个版本,假设当用户单击第一个链接时,它将发出警报“1”,第二个链接“2”,以此类推:

第1版:

<a href="#" id="link1">click me</a>
<a href="#" id="link2">click me</a>
<a href="#" id="link3">click me</a>
<a href="#" id="link4">click me</a>
<a href="#" id="link5">click me</a>

<script type="text/javascript">
    for (i = 1; i <= 5; i++) {
        document.getElementById('link' + i).onclick = (function() {
            return function() {
                var n = i;
                alert(n);
                return false;
            }
        })();
    }
</script>


for(i=1;i版本1不起作用,因为循环创建的每个“单击”处理程序函数都共享一个公共变量“i”(在本例中是一个全局变量,因为您忘记了
var


在第二个版本中,您使用小包装器函数创建了一个新的词法作用域。这使每个“click”处理程序都有自己的私有“i”.

在第二个示例中,您创建了一个var
n=i;
它将
i
值限定在onclick函数的范围内。而在第一个示例中,onclick函数仍然使用
i
的全局值

我建议改用这种用法:

  for (i = 1; i <= 5; i++) {
    document.getElementById('link' + i).onclick = (function(i) {
      return function() {
        alert(i); 
        return false;
      }
    })(i);
  }

for(i=1;iFirst不起作用,因为:i是每个闭包的一部分。经过5次迭代后,由于后缀增量运算符,现在i为6。每次调用事件处理程序时,它都会从其闭包范围中获取i的值,该范围始终为6


第二部分起作用:因为每个闭包在n中复制i,n是每个闭包的一部分。

从版本1看,它不是每次都复制一个新的
i
吗?不。在版本1中。它在迭代foreach时不复制。但它在单击时复制。
  for (i = 1; i <= 5; i++) {
    document.getElementById('link' + i).onclick = (function(i) {
      return function() {
        alert(i); 
        return false;
      }
    })(i);
  }