JavaScript 闭包 Closure

【闭包】前端的“保护神”——闭包详解+底层原理 它们能够保持对外部数据(如事件触发时的状态、函数参数等)的访问,即使在异步操作完成后,闭包仍然能够访问这些数据。你可以将某些功能封装在闭包内部,外部只能通过公开的方法调用它们,从而达到隐藏细节、减少外部依赖的目的。闭包提供了数据封装的能力,可以将状态和行为封装在一个函数内部,并通过暴露的接口与外部进行交互。闭包可以用于权限管理和角色管理的场景中,通过闭包来封装不同角色的权限信息,从而提供灵活的权限控制。是私有的,外部无法直接访问。,即使这个函数在外部被调用时,依然能访问到其定义时的父函数的局部变量。 阅读详情

前置知识:需要了解作用域

闭包的概念:

MDN:

闭包是由捆绑起来(封闭的)的函数和函数周围状态(词法环境)的引用组合而成。

提取这句话中两个关键词并用公式表示:

闭包 = 捆绑起来(封闭的)的函数 + 函数周围状态(词法环境)

简单点来说,根据黑马pink老师的话,就是

闭包 = 内层函数 + 外层函数的变量

再用图像来理解,或许能清晰一点

接下来用代码表示

function outer() {
    const fruit = 'apple'
    function inner() {
        console.log(fruit)
    }
    inner()
}
outer()

当我们调用outer方法时,代码从上往下执行,先声明并赋值了一个变量fruit,接下来声明了内部方法inner,然后开始调用内部方法inner,从而在控制台打印出'apple'。

当然,这时候,不禁就要问了,如果我们只是为了打印出‘apple’,这样做岂不是多此一举?

没错,确实是多此一举,这样写只是为了方便理解闭包的概念,而闭包的主要作用并不在此。

闭包的应用:

先来看一个场景

页面中有一个按钮,每点击一次,就让控制台打印出点击的次数,代码如下所示:

    <button>按钮</button>
    <script>
        let num = 0
        function add() {
            num++
            console.log(`按钮被点击了${num}次`)
        }
        document.querySelector('button').addEventListener('click', add)
    </script>

此时变量的num声明于全局作用域下,是一个全局变量,很容易被修改,我们希望这个num变量,只用来记录这个button,那么怎样才能让他更安全一点呢?我们就可以用到闭包,从而实现数据私有化!

在实现闭包前,我们先回想下闭包的公式,其中两个关键元素,内层函数和外层函数的变量,那么在这个方法中,谁是内层函数,谁是外层函数的变量呢?

内层函数就是我们真正要执行的逻辑

外层函数的变量就是执行这块逻辑要用到的变量

外层函数的作用就是把他们包起来

因此,内层函数就是add这个函数,而外层函数变量则是num这个变量

接下来,我们只差一个外层函数把他们包起来了,同时不要忘记把内层函数调用一次

然而,当我们打开控制台后, 事情并没有朝着我们希望的方向进行

无论点击了多少次,num仍然为1!

这是因为我们每次点击按钮时,outer被调用,然后重新定义num变量并将其初始化为0,接着在内部的add方法使得num加一。

那么怎样才能保留num的状态?

为了解决这个问题,我们需要使用return关键字,将内部函数add返回出去,再用一个新变量接受它,最后,每次点击时调用这个新变量。

这样说有点生硬,为了方便解释,我添加了一句log在初始化num后面

代码如下:

function outer() {
    let num = 0
    console.log('num', num)
   
    return function() {
        num++
        console.log(`按钮被点击了${num}次`)
    }
}

const returnOuter = outer() // 方法加上括号,表示调用

document.querySelector('button').addEventListener('click', returnOuter)

整个运行的流程为

当我们打开页面时,由于我们一开始就调用了outer(),所以控制台就会打印出‘num 0’,这也说明页面已经初始化了这个num变量,同时也返回了函数给returnOuter。

类似于: 

接下来每点击一次,都会调用returnOuter这个方法,里面的num也不会被重置了

总结一下:

闭包是内层函数和外层函数变量的结合,可以实现数据的私有化(封闭数据,提供操作),同时外部也可以访问其内部的变量(正如 const returnOuter = outer())

闭包的定义,闭包是什么?闭包解决了什么问题?闭包有哪些应用场景?使用闭包应该注意什么? 闭包(Closure)是计算机科学中的一个重要概念,特别是在函数式编程中。闭包可以定义为能够读取其他函数内部变量的函数。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。闭包包含自由(未绑定到特定对象)变量,这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义的(局部变量)。 阅读详情

相关推荐

嵌入式SPI总线抽象设计:跨平台驱动与分层解耦实践

SPI(串行外设接口)是嵌入式系统中应用最广泛的同步串行通信协议,其核心价值在于高吞吐、低开销与硬件简洁性。其工作原理基于主从架构、全双工/半双工时序及片选(CS)控制,依赖CPOL/CPHA组合定义四种标准模式。在工程实践中,SPI常面临硬件资源受限、多外设共用总线、MCU平台迁移等挑战,导致驱动复用率低、维护成本高。通过结构体+函数指针实现的分层抽象——将物理总线、协议适配与设备驱动解耦,可显著提升代码可移植性与扩展性。该方法天然支持硬件SPI与GPIO模拟SPI双模式切换,并已在STM32等主流MCU

weixin_42601134的博客 60

js闭包的理解

\1. 什么叫闭包? 闭包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成 " 定义在一个函数内部的函数" 。所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。 2.闭包的产生条件? 作用域嵌套 在父级作用域里生成了一个变量 var i=0 在子作用域里使用这个变量,这样声明的那个变量 i 就是自由变量,这种作用域嵌套环境叫做闭包环境。 在内存中存在和回收站相似的机制,叫做垃圾回收机制。...

ysj1218的博客 6917

AIGC在游戏行业的应用:革新游戏开发与体验

AIGC(人工智能生成内容)技术正在深刻改变游戏行业,从开发到体验全面革新。在游戏开发中,AIGC可用于自动生成关卡、角色和剧情,提升开发效率;在资源制作中,通过AI生成场景、角色模型等,降低成本。

1666

什么是闭包?(详解闭包)

什么是闭包? 闭包的优点。 闭包的缺点。 闭包的作用。 闭包

我只是个很菜的前端 1万+

OPTISYSTEM实战指南:线性调频连续波激光雷达系统仿真设计

本文提供了一份基于OPTISYSTEM软件的线性调频连续波激光雷达系统仿真实战指南。文章详细阐述了从软件界面熟悉、核心参数设置,到发射端、信道模型、相干接收端完整系统搭建的全过程,并介绍了性能优化与高级仿真技巧,旨在帮助读者快速掌握利用OPTISYSTEM进行低成本、高效率激光雷达系统设计与验证的方法。

weixin_29288313的博客 297

别再死记硬背了!用这5个Qt Design Studio小项目,彻底玩转核心组件

本文通过5个Qt Design Studio实战项目,帮助开发者深入理解核心组件的协作与应用。从动态登录界面到游戏化任务列表,每个项目都展示了组件属性与交互设计的巧妙结合,让你不再死记硬背,而是真正掌握Qt Design Studio的核心技能。

weixin_29202213的博客 271

对闭包的理解

理解闭包

hddlsj的博客 2582

Python连接StarRocks全流程实践: SQL文件调用与Pandas混合优化

通过这种分阶段混合计算, 既能发挥StarRocks处理海量数据的性能优势, 又能保留Pandas在内存计算中的灵活性, 实现效率与功能的完美平衡.结合SQL的高效聚合与Pandas的灵活计算, 实现查询和数据处理的深度融合.该库基于SQLAlchemy 2.x开发, 仅支持Python 3.x环境.对大批量数据的写入, 建议进行分块. 分块写入较单条插入速度会有显著提升.这样可以避免python代码的查询与SQL耦合, 支持版本化管理.将DDL, DML分离为独立文件, 例如。: 调整连接复用参数。

t.y.Tang的博客 2780

js 点击闭包_学习Javascript闭包(Closure)

讲的很清楚明了,连我都懂了,要是我们大学时的老师也能这么讲课。。。他们只会放幻灯片2009年8月30日 22:29| #| 引用2009年8月30日 22:44| #| 引用呵呵,可以作为面试题了!2009年8月31日 09:30| #| 引用十三说:闭包个人感觉是一种描述函数内部的数据结构,来描述函数的运行上下文.Javascript编程精粹 这本书算是讲的比较好一点.2009年8月31日 09...

weixin_39661780的博客 206

别再纠结了!手把手教你根据项目需求选对目标检测框架(MMDetection/Detectron2/YOLOv8实战对比)

本文详细对比了三大目标检测框架MMDetection、Detectron2和YOLOv8的适用场景与实战技巧,帮助开发者根据项目需求精准选型。从毕业设计到工业落地,分析不同场景下的核心需求与框架优势,提供决策树和避坑指南,确保技术选型与项目目标高度匹配。

weixin_30342209的博客 554

请尽可能地详细说明一个VLA项目的立项训练到落地的全流程

一个机器人VLA项目的全流程是一个复杂的系统工程,它深度融合了机器人学 (Robotics)计算机视觉 (CV)和自然语言处理 (NLP)。其核心挑战在于高质量数据的获取和从仿真到现实的有效迁移。与纯粹的软件AI项目相比,它增加了硬件、物理交互和安全性的维度,但其最终能让AI走出虚拟世界、在物理世界中产生实际价值,这也是其巨大的魅力所在。

具身机器人和通用AI 303

JavaScript闭包-Closure

记录一下闭包的相关知识:概念、场景、内存泄漏、this指向

csdn1940879828的博客 1214

C#操作MySQL从入门到精通(1)——安装MySQL数据库

我们使用C#操作MySQL数据库第一步要做的就是安装MySQL数据库,本文就是详细讲解如何安装MySQL数据库。

qq_34059233的博客 964

JS基礎:Closure 閉包

JS 基礎:Closure 閉包 文章目錄JS 基礎:Closure 閉包簡介參考正文IIFE 立即執行函數(Immediately Invoked Functions Expression)Closure 閉包for 循環:使用 IIFE 建立塊級作用域PrimeCreator 質數(素數)製造機Module 模塊化Module Loader 模塊加載器結語 簡介 在 ES6 新增 let、const 的塊級作用域變量聲明,以及 import/export 等模塊化語法之前,只能透過 var 以及,IIF

超悠閒的博客 360

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

javascript中的闭包closure详解

闭包closure是javascript中一个非常强大的功能。所谓闭包就是函数中的函数,内部函数可以访问外部函数的作用域范围,从而可以使用闭包来做一些比较强大的工作。 今天将会给大家详细介绍一下闭包。

程序那些事 6211

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

什么是Javascript闭包(Closure)

转自: 《阮一峰的网络日志》http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。 下面就是我的学习笔记,对于Javascript初学者应该是很有用的。 一、变量的作用域 要理解闭包,首先必须理解...

Littlemotor 2313

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

[JS]学习Javascript闭包(Closure)

转自:阮一峰 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。 下面就是我的学习笔记,对于Javascript初学者应该是很有用的。 一、变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域。 变量的作用域无非就是两种:全局变量和局部变量。 Javascript语言的特殊之处,就在于函数内部可以直接...

weixin_30341745的博客 86

JavaScript_个人笔记8_js的闭包closure

JAVASCRIPT闭包

rainychan2009的专栏 496

js闭包之初步理解( JavaScript closure)

闭包一直是js中一个比较难于理解的东西,而平时用途又非常多,因此不得不对闭包进行必要的理解,现在来说说我对js闭包的理解。 要理解闭包,肯定是要先了解js的一个重要特性,回想一下,那就是函数作用域,作用域分全局和局部,由于作用域链的存在,全局变量能在任何地方被访问到,相反,局部变 量只能在局部访问,而无法在全局的作用域中被访问。因为如果你想访问某个局部变量,首先搜索当前作用域...

weixin_30567471的博客 134

JavaScript学习总结二:js闭包(Closure)概念

闭包的两个特点: 1、作为一个函数变量的一个引用,当函数返回时,其处于激活状态。 2、一个闭包就是当一个函数返回时,一个没有释放资源的栈区。   概念描述(个人理解仅供参考): 当一个函数嵌套中又嵌套了其他的函数时,我们可以把它们叫做外层函数和内嵌函数。内嵌函数可以访问外层函数中定义的变量(局部变量)。假设内嵌函数用到了外层函数的变量,如果我们又把内嵌函数做为外层函数的返回值,让外界可以...

weixin_34185364的博客 94

JavaScript闭包(closure)

转自:http://blog.leapoahead.com/2015/09/15/js-closure/ 作用域:其作用的范围 作用域链:js 特有的 可访问函数外部变量 C/C++ 不可以哦 我研究JavaScript闭包(closure)已经有一段时间了。我之前只是学会了如何使用它们,而没有透彻地了解它们具体是如何运作的。那么,究竟什么是闭包? Wikipedia 给出的解释并没有太大的帮助。闭包是什么时候被创建的,什么时候被销毁的?具体的实现又是怎么样的? "use strict"; va

日积月累的博客 257

JavaScript对象系统深入剖析-4.Scope和Closure(闭包

4.       Scope和Closure @吴穹Adam(新浪) 注: 在阅读本节之前,请先阅读1-3: http://www.2cto.com/kf/201201/117897.html http://www.2cto.com/kf/201201/117898.html http://www.2cto.com/kf/201202/118315.html Sco

xuehaiwuya_1的专栏 651

JavaScript 初识闭包closure及总结

点击这里即可获取,包括答案解析。较高,非无偿)**点击这里即可获取,包括答案解析。[外链图片转存中…(img-hK4TvHDH-1711671568542)]

2401_83817171的博客 816

Java Script Closure(js闭包)-浅谈

链接:https://blog.youkuaiyun.com/Tacks/article/details/78704922 本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。 转载于:https://www.cnblogs.com/xiaolangzhong/p/10089475...

weixin_30819163的博客 142
上一篇: js 原型链
下一篇: React 配置跨域
前端开发洋洋
博客等级 码龄3年 77粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值