包 (Closures)

闭包是 JavaScript 中一个非常强大的特性,它允许函数访问其外部作用域中的变量,即使在该函数被调用时,外部作用域已经执行完毕。闭包可以帮助我们实现数据的私有化、封装和模块化,使代码更简洁、易读和可维护。

闭包的定义

简单来说,闭包是指有权访问另一个函数作用域中变量的函数。

function outerFunction() {
let outerVariable = "I am outside!"; function innerFunction() {
console.log(outerVariable); // innerFunction 可以访问 outerVariable
} return innerFunction;
} const closure = outerFunction();
closure(); // 输出: I am outside!

在上述例子中,innerFunction 就是一个闭包,它可以访问 outerFunction 中的 outerVariable,即使 outerFunction 已经执行完毕。

闭包的应用
  1. 数据私有化
function createCounter() {
let count = 0;
return function() {
count++;
return count;
};
} const counter = createCounter();
console.log(counter()); // 输出: 1
console.log(counter()); // 输出: 2
console.log(counter()); // 输出: 3

在这个例子中,count 变量被封装在 createCounter 函数的作用域内,只能通过返回的闭包函数进行访问和修改。

  1. 模拟块级作用域

在 ES6 之前,JavaScript 没有块级作用域,我们可以使用闭包来模拟块级作用域。

for (var i = 1; i <= 3; i++) {
(function(i) {
setTimeout(function() {
console.log(i);
}, i * 1000);
})(i);
}
// 输出: 1, 2, 3 (每隔一秒输出一个数字)

通过立即执行函数表达式 (IIFE),为每次循环创建了一个新的作用域,从而使 setTimeout 中的 i 保持正确的值。

事件委托 (Event Delegation)

事件委托是一种利用事件冒泡机制,将事件监听器添加到父元素上,从而管理多个子元素事件处理的一种技术。它可以减少内存占用,提高性能,特别是在需要处理大量动态生成的子元素事件时非常有用。

事件委托的定义

通过将事件监听器添加到父元素上,当子元素的事件被触发时,事件会冒泡到父元素,由父元素的事件监听器进行处理。

<ul id="parent">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
document.getElementById('parent').addEventListener('click', function(event) {
if (event.target.tagName === 'LI') {
console.log(event.target.innerText); // 输出点击的列表项的文本
}
});

在这个例子中,我们只为 ul 元素添加了一个点击事件监听器,但可以处理所有 li 元素的点击事件。

事件委托的应用
  1. 动态内容

当页面上有大量动态生成的元素时,使用事件委托可以简化事件处理。

const list = document.getElementById('parent');
document.getElementById('addItem').addEventListener('click', function() {
const newItem = document.createElement('li');
newItem.innerText = `Item ${list.children.length + 1}`;
list.appendChild(newItem);
});
  1. 提高性能

当需要为大量元素添加事件监听器时,事件委托可以显著提高性能,因为只需要为父元素添加一个事件监听器,而不是为每个子元素添加。

<button id="addItem">Add Item</button>
<ul id="parent">
<!-- 动态生成的列表项 -->
</ul>

总结

闭包能够访问外部函数作用域中的变量,从而实现数据私有化和封装;

事件委托利用事件冒泡机制,通过将事件监听器添加到父元素上,简化了事件处理,提高了性能。

JavaScript 中的闭包和事件委托的更多相关文章

  1. JavaScript中的闭包理解

    原创文章,转载请注明:JavaScript中的闭包理解  By Lucio.Yang 1.JavaScript闭包 在小学期开发项目的时候,用node.js开发了服务器,过程中遇到了node.js的第 ...

  2. javaScript中的闭包原理 (译)

    这篇文章通过javaScript代码解释了闭包的原理,来让编程人员理解闭包.它不是写给大牛或使用功能性语言进行编程的程序员的.一旦意会了其核心概念,闭包理解起来并不难.然而,你不可能通过阅读任何有关闭 ...

  3. 让你分分钟学会Javascript中的闭包

    Javascript中的闭包 前面的话: 闭包,是 javascript 中重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,你很难从定义去理解它 ...

  4. 难道这就是JavaScript中的"闭包"

    其实对于JavaScript中的"闭包"还没真正理解,这次在实际Coding中似乎遇到了"闭包"的问题,仅此摘录,以待深究. 表现为jQuery的post方法回 ...

  5. 探究JavaScript中的五种事件处理程序

    探究JavaScript中的五种事件处理程序 我们知道JavaScript与HTML之间的交互是通过事件实现的.事件最早是在IE3和Netscape Navigator 2中出现的,当时是作为分担服务 ...

  6. 在Javascript中监听flash事件(转)

    在Javascript中监听flash事件,其实有两种做法: 1.在特定的环境下(例如专门制作的flash),大家约定一个全局函数,然后在flash的事件中用ExternalInterface.cal ...

  7. 浅谈JavaScript中的闭包

    浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...

  8. javascript中的闭包解析

    学习javaScript已经有一段时间了,在这段时间里,已经感受到了JavaScript的种种魅力,这是一门神奇的语言,同时也是一门正在逐步完善的语言,相信在大家的逐步修改中,这门语言会逐步的完善下去 ...

  9. JavaScript中的鼠标滚轮事件详解

    JavaScript中的鼠标滚轮事件详解/*Firefox注册事件*/ ~~~Firefox: addEventListener('DOMMouseScroll', handler, false)if ...

  10. 【JS】JavaScript中的闭包

    在JavaScript中,闭包指的是有权访问另一个函数作用域中的变量的函数:创建闭包最常见的方式就是在一个函数内创建另一个函数.如下例子: function A(propertyName){ retu ...

随机推荐

  1. SQL必知必会(第5版) 读书笔记

    适用范围 本书涵盖的DBMS一般来说,本书中所讲授的SQL可以应用到任何数据库管理系统(DBMS).但是,各种SQL实现不尽相同,本书介绍的SQL主要适用于以下系统(需要时会给出特殊说明和注释): ❑ ...

  2. 虚拟机ping不通物理机 PING 192.168.10.1 (192.168.10.1) 56(84) bytes of data.

    准备做samba服务配置的时候 ping 192.168.10.1 (物理机地址) PING 192.168.10.1 (192.168.10.1) 56(84) bytes of data. 查看自 ...

  3. html2canvas + jspdf导出pdf,文字重叠,样式不显示或者文字不显示

    先在html引入cdn <script src="https://html2canvas.hertzen.com/dist/html2canvas.js"></s ...

  4. switch的穿透

      // switch 的 穿透         // 什么是switch的穿透         // 如果在 switch 中没有定义break , switch 会从定位的程序,一直执行到所有sw ...

  5. sql数据的操作

      /*             数据的写入                 名称 : 库名 表名 字段名 用 反引号包裹                 数据 : 字符串数据使用单引号包裹      ...

  6. CTF反序列化wp(ciscn,nss,ctfshowweb入门)

    [CISCN 2023 华北]ez_date 题目: <?php error_reporting(0); highlight_file(__FILE__); class date{ public ...

  7. Java动态获取实现类 Class.forName(clazz).newInstance()和applicationContext.getBean, bean Map寻找方式,Java Map定义和初始化方法

    Java动态获取实现类 Class.forName(clazz).newInstance()和applicationContext.getBean, bean Map寻找方式,Java Map定义和初 ...

  8. MySQL查询关于区分字母大小写问题

    前段时间在工作中测试提出了一个BUG,让我把根据ID查询区分大小写的功能去掉,大小写都随便查,然后我在SQL的位置加上了UPPER(id) = UPPER(#{id})的写法,而同事知道这个问题后的反 ...

  9. Mybatis.xml文件中 大于小于等于

    Mybatis中 大于小于等于的转义写法第一种写法:符号    转义字符<    <<=    <=>    >>=    >=&    &am ...

  10. SQLite vs MySQL vs PostgreSQL对比总结

    开发业务系统时,是绕不开RDBMS(关系型数据库)的.虽然现在诞生了各种NoSQL的数据库,RDBMS在业务系统中的严谨和优势依然无法取代. 近几年大大小小的项目中,常用的三种RDBMS(SQLite ...