简体   繁体   English

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

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

There are two versions, supposedly when the user click the first link, it will alert "1", and the second link, "2", etc.: 有两个版本,据说当用户点击第一个链接时,它会提醒“1”,第二个链接,“2”等:

Version 1: 版本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>

Version 2: 版本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>

Version 1 will not work. 版本1不起作用。 Version 2 will. 版本2将。 I think I know the reason why, but would like to compare with other people's explanations as to why version 1 doesn't work. 我想我知道原因,但想与其他人的解释比较为什么版本1不起作用。

Version 1 does not work because there's a common variable "i" (a global variable in this case, because you forgot var ) that is shared by every "click" handler function the loop creates. 版本1不起作用,因为有一个公共变量“i”(在这种情况下是一个全局变量,因为你忘了var ),它由循环创建的每个“click”处理函数共享。

In the second version, you create a new lexical scope with the little wrapper function. 在第二个版本中,您使用小包装函数创建一个新的词法范围。 That gives each "click" handler it's very own private "i". 这给每个“点击”处理程序它是非常自己的私人“我”。

In the second example you create a var n = i; 在第二个示例中,您创建了一个var n = i; it makes i value scoped inside the onclick function. 它使i值在onclick函数范围内。 While at the first one the onclick function still uses global value of i 在第一个时,onclick函数仍然使用i全局值

I'd suggest this usage instead: 我建议用这个用法:

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

In this case you'll get the same behaviour since i will be the local variable for onclick function as it's an argument. 在这种情况下,你会得到相同的行为,因为i将是onclick函数的局部变量,因为它是一个参数。

First does not work because: i is the part of each closure. 首先不起作用,因为:我是每个闭包的一部分。 After 5 iterations now i is 6 due to postfix increment operator. 经过5次迭代后,由于后缀增量运算符,我才6。 Each time when event handler is invoked it gets the value of i from its closure scope that is always 6. 每次调用事件处理程序时,它从其闭包范围获取i的值,该范围始终为6。

Second part works: because each closure makes a copy of i in n, n is part of each closure. 第二部分有效:因为每个闭包都在n中复制i,n是每个闭包的一部分。

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

相关问题 Javascript Curry:为什么一个闭包作用域示例有效,而另一个不起作用? - Javascript currying: why does one closure scope example work, but another doesn't? 为什么一个功能起作用而另一个功能不起作用? (JavaScript)的 - Why does one function work and the other one doesn't work? (Javascript) 为什么此javascript闭包无效? - Why doesn't this javascript closure work? 为什么一个计数器起作用而另一个计数器不起作用? (闭包?) - Why does one counter work and the other doesn't? (Closures?) 为什么一个AngularJS服务绑定起作用而另一个不起作用 - Why does one AngularJS service bind work but the other doesn't 为什么此行Javascript有效,而另一行无效? - Why does this line Javascript work, but the other doesn't? 为什么这个javascript闭包无法正常运行? - Why doesn't this javascript closure work as I hoped? 在Javascript中使用闭包时,为什么mouseover事件不起作用? - Why doesn't the mouseover event work when use closure in Javascript? Javascript:闭包中的缓存不起作用 - Javascript: Caching within Closure doesn't work 为什么一个变量起作用,而另一个不起作用,这两个变量非常相似 - Why does one variable work, while the other one doesn't, and the two variables are very similiar
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM