首页 > web前端 > js教程 > 为什么我的 JavaScript 循环在附加事件处理程序时总是输出计数器变量的最终值?

为什么我的 JavaScript 循环在附加事件处理程序时总是输出计数器变量的最终值?

Linda Hamilton
发布: 2024-12-28 05:40:15
原创
847 人浏览过

Why Does My JavaScript Loop Always Output the Final Value of the Counter Variable When Attaching Event Handlers?

JavaScript 臭名昭著的循环异常:解释

当尝试使用循环将事件处理程序附加到动态生成的元素时,就会出现臭名昭著的 JavaScript 循环问题。在以下代码片段中:

function addLinks() {
  for (var i = 0, link; i < 5; i++) {
    link = document.createElement("a");
    link.innerHTML = "Link " + i;
    link.onclick = function () {
      alert(i); // WRONG: i will always be 5
    };
    document.body.appendChild(link);
  }
}
登录后复制

单击任何生成的链接时,警报始终显示“链接 5”。这是因为用 var 定义的 JavaScript 变量是函数作用域的,而不是块作用域的。当循环结束时,i 保持值 5,所有内部函数都会引用它,从而得到统一的输出。

更正的解决方案在于捕获闭包内 i 的值。考虑这个片段:

function addLinks() {
  for (var i = 0, link; i < 5; i++) {
    link = document.createElement("a");
    link.innerHTML = "Link " + i;
    link.onclick = function (num) { // Closure around i
      return function () {
        alert(num); // num retains its original value
      };
    }(i); // Execute the outer function immediately to capture i
    document.body.appendChild(link);
  }
}
登录后复制

在这种情况下,num 绑定到每次迭代的 i 的当前值。当执行内部函数时,num 始终设置为循环执行时 i 的值。

此外,存在一种利用 DOM 节点存储数据的有效替代方案:

function linkListener() {
  alert(this.i);
}

function addLinks() {
  for (var i = 0; i < 5; ++i) {
    var link = document.createElement('a');
    link.appendChild(document.createTextNode('Link ' + i));
    link.i = i;
    link.onclick = linkListener;
    document.body.appendChild(link);
  }
}
登录后复制

通过将信息附加到 DOM 元素本身,避免了对额外函数对象的需求,从而提高了效率。

以上是为什么我的 JavaScript 循环在附加事件处理程序时总是输出计数器变量的最终值?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板