繁体   English   中英

为什么一个JavaScript闭包工作而另一个没有?

[英]Why does one JavaScript closure work and the other doesn't?

有两个版本,据说当用户点击第一个链接时,它会提醒“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>

版本2:

<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() {
            var n = i;
            return function() {
                alert(n);
                return false;
            }
        })();
    }
</script>

版本1不起作用。 版本2将。 我想我知道原因,但想与其他人的解释比较为什么版本1不起作用。

版本1不起作用,因为有一个公共变量“i”(在这种情况下是一个全局变量,因为你忘了var ),它由循环创建的每个“click”处理函数共享。

在第二个版本中,您使用小包装函数创建一个新的词法范围。 这给每个“点击”处理程序它是非常自己的私人“我”。

在第二个示例中,您创建了一个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);
  }

在这种情况下,你会得到相同的行为,因为i将是onclick函数的局部变量,因为它是一个参数。

首先不起作用,因为:我是每个闭包的一部分。 经过5次迭代后,由于后缀增量运算符,我才6。 每次调用事件处理程序时,它从其闭包范围获取i的值,该范围始终为6。

第二部分有效:因为每个闭包都在n中复制i,n是每个闭包的一部分。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM