包 (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. python-将多个表格的信息合并到一个表格中

    1.环境 代码运行环境:python3.7 相关的库:xlrd.xlwt 2.目的 通过xlrd库读取各个表格的数据,通过xlwt库将读取到的数据写入到一个表格中. 3.实现 在工程目录下,有一个te ...

  2. C#/.NET/.NET Core优秀项目和框架2024年5月简报

    前言 公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架(每周至少会推荐两个优秀的项目和框架当然节假日除外),公众号推文中有项目和框架的介绍.功能特点.使用方式以及部分功能截图 ...

  3. vue3 Suspense

    在Vue.js 3中,Suspense 是一个用于处理异步组件的特殊组件,它允许你在等待异步组件加载时展示备用内容.这对于优化用户体验.处理懒加载组件或异步数据获取时非常有用.Suspense 的主要 ...

  4. while适用于不确定循环次数

      // 当前有一个随机数,是生成100-999的随机数值         // 需要生成数值666,需要知道循环了多少次,才生成的666这个数值         // 我们可以通过循环来实现     ...

  5. NCNN的内存显存分配器ncnn::Allocator & ncnn::VkAllocator翻译及其差异对比的学习笔记(nihui亲审过滴)

    NCNN的内存分配器 ncnn::Allocator 通用内存分配器   ncnn::PoolAllocator 内存池分配器 可以设置池大小,减少分配内存和析构内存次数,空间换时间   ncnn:: ...

  6. 关于朋友圈出现的小米新店广告骗局(非法获取个人消息)木马通过广东政务服务网(tyrz.gd.gov.cn)的url漏洞显示

    前两天在朋友圈突然看到有发 小米新店开业 送千台扫地机器人的 广告,出于天上不会掉馅饼到我身上的原则 我选择忽略了,但是没多久 看到他又晒了个物流订单,于是还是点开看了一下,发现微信打开的网站还蛮正规 ...

  7. 反外挂 DDos UDP 攻击只需客户端 开着游戏客户端

    #include<WINSOCK2.H> #include<iostream> #include<string> using namespace std; #inc ...

  8. EF 开始的片段时有问题 具有潜在运行时冲突

    错误 3002: 映射从第 149 行开始的片段时有问题:表 t_Apply  的键(t_Appl .Id)具有潜在运行时冲突: 列(t_Apply .Id)映射到概念端 EntitySet t_Ap ...

  9. FlashDuty Changelog 2023-09-21 | 自定义字段和开发者中心

    FlashDuty:一站式告警响应平台,前往此地址免费体验! 自定义字段 FlashDuty 已支持接入大部分常见的告警系统,我们将推送内容中的大部分信息放到了 Lables 进行展示.尽管如此,我们 ...

  10. 使用 OpenTelemetry 构建可观测性 04 - 收集器

    在之前的博文中,我们讨论了如何使用 SDK 和链路追踪生产者来导出进程中的遥测数据.尽管有多种类型的导出器可供选择,但其中一个常见的目标是将数据导出到 OpenTelemetry Collector. ...