JavaScript中的闭包:原理与实战

news/2025/11/2 15:32:28/文章来源:https://www.cnblogs.com/yjh3524/p/19185018

在JavaScript的世界里,闭包(Closure)是一个既强大又难以理解的概念。它不仅是函数式编程的核心,也是许多高级JavaScript特性和库(如React的Hooks、jQuery的事件处理等)的基础。本文将深入探讨闭包的原理,并通过代码演示其在实战中的应用。

什么是闭包?

闭包是指一个函数能够记住并访问它的词法作用域,即使这个函数在其词法作用域之外执行。换句话说,闭包使得函数能够“捕获”并“记住”它定义时的环境(即外部函数的变量和参数),并在后续调用时访问这些环境变量。

闭包的原理

JavaScript中的函数在创建时会生成一个称为“执行上下文”(Execution Context)的对象,这个对象包含了函数执行时所需的所有信息,包括变量、函数声明和词法作用域链(Lexical Scope Chain)。当函数被调用时,它的执行上下文会被推入调用栈(Call Stack),并在函数执行完毕后从栈中弹出。

然而,当函数作为另一个函数的返回值或参数时,它的执行上下文并不会立即被销毁。相反,它会保留下来,以便在后续调用时访问。这就是闭包的基本原理:函数记住了它的词法作用域,即使这个函数已经不在它的原始作用域内执行。

代码演示:闭包在实战中的应用

  1. 数据封装与私有变量

闭包可以用来模拟私有变量,因为内部函数可以访问外部函数的变量,但外部函数之外的代码无法直接访问这些变量。

function createCounter() {let count = 0; // 私有变量return {increment: function() {count++;return count;},decrement: function() {count--;return count;}};
}const counter = createCounter();
console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
console.log(counter.decrement()); // 1

在这个例子中,createCounter函数返回了一个对象,该对象包含了两个方法:incrementdecrement。这两个方法都可以访问和修改count变量,但外部代码无法直接访问count

  1. 回调函数与事件处理

闭包在回调函数和事件处理中也非常有用。例如,在设置事件监听器时,我们通常会传递一个函数作为回调,这个函数可以访问定义时的环境变量。

function createButton(text, onClick) {const button = document.createElement('button');button.textContent = text;button.addEventListener('click', onClick);return button;
}let clickCount = 0;
const button = createButton('Click Me', function() {clickCount++;console.log('Button clicked ' + clickCount + ' times.');
});document.body.appendChild(button);

在这个例子中,createButton函数接受一个文本和一个回调函数作为参数,并创建一个按钮。当按钮被点击时,回调函数被调用,并访问和修改外部的clickCount变量。

  1. 模拟块级作用域

在ES6之前,JavaScript没有块级作用域(只有函数级作用域)。闭包可以用来模拟块级作用域,从而避免变量提升(Hoisting)和意外的变量覆盖。

for (var i = 0; i < 3; i++) {(function(j) {setTimeout(function() {console.log(j);}, 1000);})(i);
}

在这个例子中,我们使用了立即调用的函数表达式(IIFE)来创建一个新的作用域,并将循环变量i作为参数传递给这个函数。这样,每个setTimeout回调都有自己的j变量副本,避免了变量提升和覆盖的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/953643.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Zabbix执行Ping脚本报错,Global script execution被禁用

全局脚本是一种 可以在 Zabbix 前端执行的自定义操作命令,管理员可以通过 Web 界面配置,然后在触发告警或手动执行时,由 Zabbix Server 端执行对应的命令脚本。默认情况下是禁用的,由zabbix配置文件EnableGlobalSc…

windows---无法删除文件解决办法

对于一些流氓软件,已经卸载了,但是文件还在,还是依旧无法删除,例如这样:或者这样:我们可以右键:查看文件名复制名称,然后【Ctrl+Alt+Del】打开任务管理器,打开【性能】打开【打开资源监视器】然后点击【CPU】…

2025 年 11 月氨糖厂家最新推荐,聚焦资质、案例、售后的五家机构深度解读

氨糖市场的快速发展使得厂家资质合规性、合作案例可靠性与售后服务完善度成为选购关键。本次推荐基于国际健康产品认证协会 2025 年第三季度测评数据,采用 “资质 - 案例 - 售后” 三维测评框架。资质维度,核查厂家生…

基于嵌入式无人机UAV通信系统的实时最优资源分配算法matlab仿真

1.课题概述 考虑使用UAV作为中继辅助节点的设备到设备(D2D)无线信息和电力传输系统。由于无人机的能量容量和飞行时间有限,部署无人机的一个重要问题是实时应用中的能耗管理,能耗与无人机的发射功率成正比。为了解…

2025年11月氨糖厂家最新推荐,聚焦跨平台能力与售后体系的实用指南

当前氨糖销售渠道日益多元化,厂家的跨平台运营能力与售后体系完善度,成为影响产品市场覆盖与用户体验的关键因素。本次推荐基于国际健康产业渠道协会 2025 年第三季度测评数据,采用 “跨平台能力 - 售后体系” 双维…

2025 年 11 月氨糖厂家最新推荐,高性能与可靠性兼具的优质品牌

随着氨糖产品在骨健康领域的应用愈发广泛,消费者与采购方对产品性能(如成分纯度、吸收效率)与品牌可靠性(如质量稳定性、供应保障)的要求不断提升。本次推荐基于国际骨健康产品协会 2025 年第三季度测评数据,采用…

bash 终端中无法正常使用python

Hello World本文来自博客园,作者:南宫影,转载请注明原文链接:https://www.cnblogs.com/nangongying/p/19184998

MSYS静态编译dav1d最新版本步骤

1. 下载 meson-1.9.1-64.msi 并安装 2. 下载最新dav1d-20251101-f9799593 3. 解压源码到dav1d-20251101-f9799593目录 4. 修改dav1d-20251101-f9799593\package\crossfiles\i686-w64-mingw32.meson文件我的gcc版本是15…

rust学习(四)变量与数据类型

创建项目cargo new variables cd cargo变量 编写代码 fn main() {let x: i32 = 12;println!("The value of x is: {x}");x = 6;println!("The value of x is: {x}"); }这段代码如果在RustRover内…

构建现代Web应用:使用React框架打造单页面应用

1. React简介 React是一个用于构建用户界面的JavaScript库,由Facebook开发并维护。React的设计理念是将复杂的UI分解成独立的组件,这样可以更方便地管理和复用代码。此外,React还通过虚拟DOM技术提高了应用的性能。…

基于有限体积法(FVM)的MATLAB流体力学求解程序

一、基础框架代码(二维稳态不可压缩流动) %% 初始化参数 Lx = 0.1; Ly = 0.01; % 计算域尺寸 Nx = 50; Ny = 20; % 网格数 dx = Lx/Nx; dy = Ly/Ny;% 物理参数 rho = 1.2; mu = 1.8e-5; nu = mu/rho; % 空气物性 …

证明:割空间以及环空间的直和为边空间当且仅当图的生成树个数为偶数

一个线性代数的证明。命题:对于连通图 \(G=(V,E)\),记其割空间为 \(A\),环空间为 \(B\),边空间为 \(E\),则 \(A\oplus B=E\) 当且仅当图 \(G\) 的生成树个数为奇数。 证明: 由于 \(\dim A+\dim B=\dim E\),所以…

langgraph-reflexion

langgraph-reflexion https://github.com/fanqingsong/langgraph-reflexion/tree/main Implementation of a sophisticated Reflexion agent using LangGraph and LangChain, designed to generate high-quality respo…

WC 2026 备战记录

CSP 2025 炸了,意识到 CTT 再炸就没有 WC 玩了,很生气! 记录了日常训练中的一些题。 目录

面向院区病房的空间智能体新范式:下一代病房框架研究(上)

面向院区病房的空间智能体新范式:下一代病房框架研究(上)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Conso…

JSR 303 常用注解及示例

JSR 303 常用注解及示例JSR 303 常用注解及示例 ✅ JSR 303 常用注解及示例注解 作用 示例@NotNull 值不能为 null @NotNull(message = "ID不能为空")@NotBlank 字符串不能为空(非 null 且去除空格后长度 &…

实用指南:用 Go 并发优化用户中心 API:goroutine 和 errgroup 的实战魔法

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

MySQL02 函数

MySQL02 函数函数 字符串函数调用方式:SELECT F(x) 或和其他语法结合使用 update user set id = lpad(id,4,0);一般来说都是更新,先选中表,再对对象调用函数,用等于号连接。 数值函数 CEIL(X)//向上取整 FLOOR(X)/…

夸克网盘免费领取1TB空间的方法

一、活动时间 2025年01月01日 ~ 2026年12月31日 二、面向用户 夸克 App 新用户,即在手机端和 PC 端从未使用手机号注册过夸克账号的用户只安装过夸克客户端但从未注册夸克账号的用户,也可获得本次新用户活动奖励; …