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

yizhihongxing

下面是关于“浅谈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日

相关文章

  • Javascript基础知识中关于内置对象的知识

    Javascript基础知识中关于内置对象的知识 Javascript中内置对象是指在语言中定义好的一些对象,可以直接使用,不需要进行任何的定义或引入。常见的内置对象有:String、Number、Boolean、Object、Array、Function、RegExp、Date等。 String对象 String对象表示文本字符串。它可以通过字面量、变量等…

    JavaScript 2023年6月10日
    00
  • JS实现轮播图小案例

    JS实现轮播图小案例的攻略如下: 1. 设计HTML结构 在页面上设计轮播图的HTML结构,通常采用ul标签加li标签的方式,li标签内嵌套img标签。同时也可以添加左右切换箭头、小圆点等控件。 示例代码: <div class="slider"> <ul class="slider-list"&gt…

    JavaScript 2023年6月11日
    00
  • JS.findElementById()使用介绍

    JS.findElementById()使用介绍 在JavaScript中,document.getElementById()方法允许您通过DOM(Document Object Model)获取HTML元素。该方法将返回具有指定ID的元素。 语法 以下是 document.getElementById() 的语法: document.getElementB…

    JavaScript 2023年6月10日
    00
  • js实现接收表单的值并将值拼在表单action后面的方法

    实现接收表单的值并将值拼在表单action后面的方法,可以通过以下步骤来完成: 使用 HTML 表单标签创建表单,并指定表单的 action 和 method 属性以及 input 标签来定义表单项。 <form action="submit.php" method="post"> <label fo…

    JavaScript 2023年6月10日
    00
  • 当前流行的JavaScript代码风格指南

    当前流行的 JavaScript 代码风格指南 在 JavaScript 社区中,有很多流行的代码风格指南,比如 Airbnb JavaScript 代码风格指南,Google JavaScript 代码风格指南等。这些指南都提供了详细的代码规范和最佳实践,帮助开发者保证代码的质量和可读性。以下是一个完整的攻略。 1. 注释和命名规范 良好的注释和命名规范可…

    JavaScript 2023年5月19日
    00
  • 详谈js中数组(array)和对象(object)的区别

    详谈JS中数组(Array)和对象(Object)的区别 在JS中,数组和对象都是非常常见且重要的数据类型。它们可以用于存储和操作数据,但是它们之间有很大的区别。本攻略将详细讲解JS中数组和对象的区别,包括定义、访问和操作数组和对象。 数组(Array)是什么? JS中的数组是一种有序、可变的集合,可以存储任意类型的值,包括数字、字符串、对象等。它通过下标来…

    JavaScript 2023年5月27日
    00
  • JavaScript中 ES6变量的结构赋值

    下面是关于“JavaScript中 ES6变量的结构赋值”的完整攻略。 什么是ES6变量的结构赋值 ES6中引入了一种新的变量赋值方式,叫做“结构赋值”(Destructuring Assignment)。结构赋值可以让我们方便地从数组和对象中提取值,然后赋值给变量。 数组结构赋值 数组结构赋值是指对于数组中的每个元素,通过相应位置上的变量名进行访问和取值赋…

    JavaScript 2023年6月10日
    00
  • Python cookbook(字符串与文本)针对任意多的分隔符拆分字符串操作示例

    标题:Python cookbook(字符串与文本)针对任意多的分隔符拆分字符串操作示例 本文介绍Python cookbook中关于针对任意多的分隔符拆分字符串的操作示例,涉及到字符串的分割、切片、正则表达式等多种方法。 示例一:使用字符串的split方法进行分割操作 在Python中,可以使用字符串的split方法对字符串进行分隔,拆分为指定分隔符的多个…

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