首页  >  文章  >  web前端  >  为什么循环中的闭包会使所有链接显示相同的值?

为什么循环中的闭包会使所有链接显示相同的值?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-10-27 21:41:30990浏览

 Why Do Closures in Loops Make All Links Display the Same Value?

循环中的 JavaScript 闭包:揭秘

理解闭包

JavaScript 中的闭包允许函数从直接外部访问变量范围,创建私有数据上下文。然而,即使封闭函数执行完毕,闭包引用的变量仍然可以访问。

循环中闭包的问题

考虑以下代码片段:

<code class="javascript">for (var i = 0; i < 5; i++) {
  link = document.createElement("a");
  link.innerHTML = "Link " + i;
  link.onclick = function (num) {
    return function () {
      alert(num);
    };
  }(i);
  document.body.appendChild(link);
}</code>

在此示例中,作为 num 传递给内部函数的 i 值由在所有链接元素之间创建“共享变量”的闭包捕获。这意味着单击任何链接将始终显示 i 的最后一个值(在本例中为 4)。

使用 IIFE(立即调用函数表达式)作为函数工厂

要解决此问题,请为每个链接创建一个 IIFE,并将 i 的值作为参数传递:

<code class="javascript">function addLinks() {
  for (var i = 0; i < 5; i++) {
    link = document.createElement("a");
    link.innerHTML = "Link " + i;

    // IIFE used as a function factory
    link.onclick = (function (num) {
      return function () {
        alert(num);
      };
    })(i);
    document.body.appendChild(link);
  }
}</code>

在此版本中,每个 IIFE 创建一个隔离范围,其中 i 的值被冻结在函数创建的时间。这确保每个链接元素都有自己的 i 私有副本,无论单击的顺序如何。

替代方法:函数生成器

另一个选项是使用函数生成器创建引用 i 当前值的函数:

<code class="javascript">function generateMyHandler(x) {
  return function () {
    alert(x);
  };
}

for (var i = 0; i < 5; i++) {
  link = document.createElement("a");
  link.innerHTML = "Link " + i;
  link.onclick = generateMyHandler(i);
  document.body.appendChild(link);
}</code>

在这种情况下,generateMyHandler 函数返回一个新函数,该函数在调用时已绑定到 i 的特定值函数调用。

通过了解 JavaScript 闭包如何捕获变量并使用适当的技术创建隔离作用域,开发人员可以有效处理涉及共享变量的复杂循环场景。

以上是为什么循环中的闭包会使所有链接显示相同的值?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn