浅谈JS闭包中的循环绑定处理程序

下面是关于“浅谈JS闭包中的循环绑定处理程序”的详细攻略。

什么是闭包

闭包指的是一个函数可以访问并修改它所在的词法作用域中的变量,即使这个函数在它所在的词法作用域外被调用。在 JavaScript 中,函数就是闭包。

为什么需要闭包

JavaScript 中引入闭包的一个重要原因是函数作用域的变量是“静态”绑定的,即它们与它们所在的上下文是在它们被定义和分配时就绑定的。而函数在运行时可以动态地创建和修改变量,所以需要利用闭包来实现动态绑定。

循环中的闭包问题

在 JavaScript 中,经常会遇到在循环中绑定事件处理程序的问题。例如,以下代码:

var buttonList = document.getElementsByTagName('button');
for (var i = 0; i < buttonList.length; i++) {
   buttonList[i].addEventListener('click', function() {
       // do something
   });
}

这段代码的意图是为按钮列表中的每个按钮绑定一个 click 事件处理程序。但由于 JavaScript 中的变量作用域是函数作用域而不是块级作用域,并且 for 循环的初始化、条件和增量都在同一个上下文中,因此在循环结束后,i 的值始终为 buttonList.length,导致所有按钮都绑定了相同的事件处理程序(点击任何一个按钮都会执行最后一个按钮的事件处理程序)。

解决方法:使用闭包

解决这个问题的一种方法是使用闭包创建一个新的函数作用域,使得每个函数都可以引用一个独立的变量 i。例如:

var buttonList = document.getElementsByTagName('button');
for (var i = 0; i < buttonList.length; i++) {
  (function(i) {
    buttonList[i].addEventListener('click', function() {
      // do something
    });
  })(i);
}

这段代码使用了一个自执行函数创建了一个新的函数作用域,局部变量 i 被复制为新的 i,使得每个函数都绑定了一个独立的点击事件处理程序。

示例:计数器

以下代码是一个计数器的示例,通过使用闭包,每个按钮都可以维护一个独立的计数器。

<button>0</button>
<button>0</button>
<button>0</button>
<button>0</button>
<script>
var buttonList = document.getElementsByTagName('button');
for (var i = 0; i < buttonList.length; i++) {
  (function(i) {
    var count = 0;
    buttonList[i].addEventListener('click', function() {
      count++;
      buttonList[i].innerHTML = count;
    });
  })(i);
}
</script>

在这个示例中,我们使用闭包创建了一个新的函数作用域,局部变量 count 和 i 被复制为新的 count 和 i,使得每个按钮都维护了一个独立的计数器。点击每个按钮都会使得对应计数器加 1。

示例:获取远程数据

以下代码是一个获取远程数据的示例,通过使用闭包,每个按钮都可以获取独立的远程数据。

<button>Load data 1</button>
<button>Load data 2</button>
<button>Load data 3</button>
<button>Load data 4</button>
<script>
var buttonList = document.getElementsByTagName('button');
for (var i = 0; i < buttonList.length; i++) {
  (function(i) {
    buttonList[i].addEventListener('click', function() {
      var xhr = new XMLHttpRequest();
      xhr.open('GET', 'https://api.example.com/data?id=' + (i + 1), true);
      xhr.onreadystatechange = function() {
        if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
          console.log(xhr.responseText);
        }
      };
      xhr.send();
    });
  })(i);
}
</script>

在这个示例中,我们使用闭包创建了一个新的函数作用域,局部变量 i 被复制为新的 i,使得每个按钮发送的请求都是独立的。点击每个按钮都发送一个请求,并输出响应数据。

通过以上两个示例,可以看到闭包的强大之处,它可以通过动态创建函数作用域,使得每个函数绑定的事件处理程序都可以引用一个独立的变量。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:浅谈JS闭包中的循环绑定处理程序 - Python技术站

(0)
上一篇 2023年6月10日
下一篇 2023年6月10日

相关文章

  • 使用Python解析JSON的实现示例

    下面我将为您详细讲解“使用Python解析JSON的实现示例”的完整攻略。 一、JSON简介 JSON全称为JavaScript Object Notation,它是一种轻量级的数据交换格式。在现代的Web应用开发中,JSON作为一种简单、易于理解的数据格式而备受推崇,常常使用在前后端数据交互、API接口等场景中。 一个JSON对象由一些键值对组成,键值对之…

    JavaScript 2023年6月11日
    00
  • js模拟点击以提交表单为例兼容主流浏览器

    以下是详细讲解“js模拟点击以提交表单为例兼容主流浏览器”的完整攻略。 什么是js模拟点击以提交表单 js模拟点击以提交表单是指在前端页面上通过JavaScript代码模拟用户点击提交按钮并提交表单数据。通常用于从前端页面向后台服务器提交数据并触发后台相关操作。 兼容主流浏览器的攻略 由于不同浏览器的JS引擎有差异,因此需要针对不同的浏览器进行兼容。 下面是…

    JavaScript 2023年5月27日
    00
  • window.parent与window.openner区别介绍

    window.parent与window.opener区别介绍 在网页中经常出现需要进行页面跳转的情况,比如新窗口打开链接,或者在iframe中嵌入其他网页。在JavaScript中有两个常用的属性可用于控制页面跳转:window.parent和window.opener。在本文中,将详细介绍这两个属性的区别以及其应用场景。 window.parent wi…

    JavaScript 2023年6月11日
    00
  • JavaScript根据json生成html表格的示例代码

    下面我将详细讲解如何使用JavaScript根据JSON数据生成HTML表格的完整攻略。 前置知识 在了解这个示例代码之前,需要你掌握一些HTML、CSS和JavaScript的基础知识,同时了解JSON数据格式以及如何创建JavaScript数组和对象。如果你还不熟悉这些知识,请先学习一下。 示例代码 下面是一个根据JSON数据动态生成HTML表格的示例代…

    JavaScript 2023年5月27日
    00
  • JavaScript中字符串与Unicode编码互相转换的实现方法

    下面是JavaScript中字符串与Unicode编码互相转换的实现方法的完整攻略。 字符串与Unicode编码互相转换的方法 在JavaScript中,字符串与Unicode编码可以互相转换。字符串是由Unicode编码组成的序列,每个字符对应一个Unicode编码。Unicode编码可以表示几乎所有的字符,包括各种语言的字母、数字、符号、标点符号、表情符…

    JavaScript 2023年5月20日
    00
  • JavaScript实现简易购物车最全代码解析(ES6面向对象)

    JavaScript实现简易购物车最全代码解析(ES6面向对象)是一篇详细讲解JavaScript购物车实现的文章,提供了完整的代码和注释,可以帮助初学者更好地理解面向对象的编程思想和JavaScript语言的运用。 该文章的实现过程主要分为以下几个步骤: 定义CartItem类 首先定义一个CartItem类,用于表示某一个商品的信息,包括商品的id、na…

    JavaScript 2023年6月10日
    00
  • CSS3+JavaScript实现炫酷呼吸效果的示例代码

    下面是我对于“CSS3+JavaScript实现炫酷呼吸效果的示例代码”的完整攻略,希望能对你有所帮助。 1.准备工作 在开始之前,我们需要先准备好相关的素材。首先是一个由多张逐渐透明的png图片组成的呼吸动画效果,还需要一个 HTML 文件和一个 CSS 文件。我们还需要在 HTML 文件中引入 jQuery 库和 CSS 文件。 下面是一个示例的 HTM…

    JavaScript 2023年6月11日
    00
  • Move.js入门

    Move.js入门攻略 什么是Move.js Move.js是一个轻量级的JavaScript动画库,用于实现Web页面中的动画效果。它支持常用的CSS动画属性以及自定义路径和缓动效果,同时具有跨浏览器兼容性和高性能特点。 安装Move.js 可以通过以下两种方式来安装Move.js: 从官方网站下载move.min.js文件并引入到HTML文件中: &lt…

    JavaScript 2023年6月10日
    00
合作推广
合作推广
分享本页
返回顶部