聊聊JavaScript闭包

关于 js 闭包的理解 函数对象可以通过作用域链相互关联起来,函数体内部变量可以保存在函数作用域内,这就是闭包。各种专业文献上的 `闭包(closure)`定义非常抽象,很难看懂。我的理解是,闭包就是能够读取其他函数内部变量的函数。所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。要理解闭包,首先必须理解Javascript特殊的变量作用域。 阅读详情

在了解闭包之前,我们先了解一下JS中的函数,JS中的函数分为定义阶段和调用阶段。

  • JS函数定义阶段
    函数在定义的时候,会在内存中开辟一个存储空间。在这个存储空间里,函数内部的代码会被当做字符串存储起来,并且函数内部的变量不会被解析。这个空间地址会赋值给函数名。
  • 函数调用阶段
    按照函数名找到相应的存储空间,从而开辟一个函数的执行空间,在执行空间会进行形参的赋值,并进行预解析,将存储空间的代码执行完毕之后,这个空间就会销毁。

如:
var num = 100

/*
  函数定义阶段
    + 在内存中开辟了一个函数存储空间(xxff00)
    + 把 console.log('数字: ' + num) 这句代码放在这个存储空间中
      => 此时 num 变量没有解析, 存储的就是 num
    + 把 xxff00 这个空间地址赋值给了 fn 这个函数名
*/
function fn() {
  console.log('数字: ' + num)
}

/*
  函数调用阶段
    + 按照 fn 里面存储的地址, 找到 xxff00 这个函数存储空间
    + 开辟一个函数执行空间(xxff11), 在运行内存里面
    + 在 xxff11 这个空间里面进行形参赋值
    + 在 xxff11 这个空间里面进行预解析
    + 把存储空间(xxff00) 里面存储的代码复制一份到这个执行空间
      => 复制一份 console.log('数字: ' + num) 过来
      => 执行这句代码的时候才解析变量 num
    + 等到代码执行完毕以后, 这个开辟的 xxff11 执行空间销毁
*/
fn()

/*
  函数再次调用
    + 按照 fn 里面存储的地址, 再次找到 xxff00 这个函数存储空间
    + 再次开辟一个函数执行空间(xxff22), 在运行内存类面
    + 在 xxff22 这个空间里面进行形参赋值
    + 在 xxff22 这个空间里面进行预解析
    + 把存储空间(xxff00) 里面存储的代码复制一份到这个执行空间
      => 复制一份 console.log('数字: ' + num) 过来
      => 执行这句代码的时候才解析变量 num
    + 等到代码执行完毕以后, 这个开辟的 xxff22 执行空间销毁

*/
fn(

函数的两个阶段

前面我们说过,函数在执行空间执行完毕,这个空间就会销毁。那么怎样让这个执行空间不销毁呢?

在特殊的情况下,函数的执行空间是不会被销毁的,如下:

  1. 当函数内部返回一个 复杂数据类型(函数,数组,对象,等等)
  2. 并且在函数外部有变量接受这个 复杂数据类型 的时候

这样执行空间就不会被销毁了。但是这不说明这个执行空间就永远不会被销毁了。 当外部接受的这个变量不在引用函数内部的返回值的时候,这个执行空间还是会销毁。
在这里插入图片描述
接下来我们就来聊聊闭包,我们先来了解一下形成闭包的三个必要条件(缺一不可)。
[1] 在函数 A 内部直接或者间接返回一个函数 B
[2] B 函数内部使用着 A 函数的私有变量
[3] A 函数外部有一个变量接收着函数 B

这样就形成了一个不会被销毁的执行空间了。我们管这个不会销毁的 a 函数的执行空间叫做 闭包空间,把函数 A 里面返回的 函数 B, 叫做函数A 的 闭包函数,如下代码所示:

function A() {
     // 这个 num 变量就是函数 a 的私有变量
    var num = 100
     return function B() {
         console.log(num)
     }
}

    // res 接受的是 a 函数执行以后的返回值
    // res 接受的就是函数 a 内部返回的一个复杂数据类型(函数b)
    //   导致函数 a 的执行空间不会销毁
var res = A()

    // 从现在开始, res 随时可以是一个 函数a 里面返回的 函数b
    //   res 随时可以调用

res()

    // 当 res 调用的时候, 打印 num
    //   打印出来的就是 a 函数内部的私有变量 num 的值

闭包
我们再来说说闭包的特点和作用,如下:

闭包的特点(优点和缺点并存)

  1. 延长了变量的生命周期
    优点: 因为执行空间不销毁, 变量也没有销毁
    缺点: 因为执行空间不销毁, 会一直存在在内存中

  2. 可以访问函数内部的私有变量
    优点: 利用闭包函数可以访问函数内部的私有变量
    缺点: 执行空间不会销毁, 会一直存在在内存中

  3. 保护私有变量(只要是函数, 就有这个特点)
    优点: 保护私有变量不被外界访问
    缺点: 如果向访问, 必须要利用闭包函数

闭包的函数的缺点可以说是致命的, 因为当一段内存空间中有一个不会被销毁的空间,那么它会一直存在,这样就会出现内存占用, 如果过多, 就会导致 内存泄漏

闭包的作用,就是当你需要延长变量的声明周期时,或者你需要访问某一个函数内部的私有数据的时候,你可以使用 闭包函数 来解决。

【高频考点精讲】闭包到底是什么?一篇文章彻底搞懂JavaScript闭包的本质与应用场景 闭包不是洪水猛兽,而是JS送给我们的超级武器。为什么React Hooks可以记住状态为什么防抖节流函数能正常工作如何实现真正的私有变量模块化开发的底层原理闭包用得好是利器,用不好就是内存炸弹。理解原理,合理使用,你就能在前端之路上越走越远!(本文由全栈老李原创,转载需注明出处) 阅读详情

相关推荐

论文阅读—Square Attack: a query-efficient black-box adversarial attack via random search

论文阅读—Square Attack: a query-efficient black-box adversarial attack via random search 发表位置 ECCV 2020 摘要 作者提出了一种基于得分的黑盒Square attack,该模型不依赖于模型的局部梯度信息,因此可以绕过梯度隐藏防御攻击。Square Attack是一种随机搜索方法,它在随机位置选择局部的方形更新,使得每次迭代时扰动近似位于可行集的边界。 背景 当涉及到对安全至关重要的机器学习应用时,对抗性的例子尤其值得

yayayamaomaoya的博客 2495

来谈谈闭包

闭包的概念 闭包解决了什么问题? 闭包带来的副作用是什么? 闭包的应用场景都有哪些? 概念 MDN 上给出的闭包的定义是:一个函数和其周围状态的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包。也就是说,闭包可以让你在一个内层函数中访问到外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。 来看个例子: function parent() { var name = 'closure'; // name 是在 parent 函数.

qq_42345237的博客 317

Qt Quick/QML入门到精通_专栏demo对应文章目录(目前50个左右demo/长期更新)

自定义图标下拉列表框的效果如下所示:自定义三态按钮的效果如下所示:传送门:53.qt quick-自定义三态按钮、自定义图标下拉列表框_诺谦的博客-优快云博客传送门:59.qt quick-qml调色板(颜色取色器)实现、自定义QQuickStyle样式_诺谦的博客-优快云博客63.qt quick-QML侧边滑动栏(不需要任何图片资源,支持自定义左右方向和大小)_诺谦的博客-优快云博客_qt实现好看侧边栏。...

抵抗时间扭曲,坚持做一件有意义的事 2万+

简单聊聊——闭包

闭包的定义 在了解闭包之前,我们首先要搞懂JavaScript的变量作用域的一些问题。 变量作用域无非就是两种: 全局作用域(全局变量) 局部作用域(局部变量) 用于 JavaScript语言 特殊之处在于:函数内部可以直接访问全局变量(var / const 定义的变量);另一方面,函数内部无法让外部使用。 所以,当我们外部需要使用函数内部定义的变量时,就需要用到“闭包” 在函数内部再定义一个函数 function f1(){ var n = 99; function f2(){ co

爱写博客的小菜鸟的博客 239

DeepSeek 赋能招投标全流程智能化:多模态解析、知识图谱与投标文件自动生成实战指南(附完整代码与行业案例)

摘要:本文深入探讨DeepSeek技术在招投标领域的全流程智能化应用,通过整合自然语言处理(NLP)、多模态解析、知识图谱等核心技术,实现招标文件智能解析与投标文件自动生成。文中详细解析DeepSeek-R1模型的多模态处理机制、动态知识图谱构建方法及智能模板填充算法,通过完整代码实现展示技术细节。结合广某资源交易平台、山西XX"XX云"等典型案例,验证技术方案在提升招投标效率、降低人为错误方面的显著效果。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 1464

CT探测器普遍采用“星形拓扑+多ADC模组”架构的TDC(时间数字转换器)设计方案

本文提出一种基于TDC反馈机制的CT探测器时钟同步方法,通过延时测量、偏差计算和动态补偿三步硬件流水线,实现高精度同步。系统采用Xilinx Kintex UltraScale FPGA内置CARRY8进位链构建3.5ps分辨率的TDC,结合多级比较器和延迟单元,形成闭环反馈控制。实验表明,在512通道、1.28m传输距离下,同步精度稳定在10ps以内,较传统方案提升两个数量级,并能动态补偿干扰抖动。该方案解决了传统方法在CT旋转腔体环境下精度不足的问题,为下一代超高清CT提供了有效的时钟同步解决方案。

whm128的博客 275

javascript闭包及其使用场景

概念 先看一段代码 function t1(){ var age = 22; function t2(){ alert(age); } return t2; } var tmp = t1(); var age = 99; tmp();//22 在大部分的语言中,t1被调用执行,则申请内存,并把局部变量push入栈。t1函数执行完毕,内部的局部变量随着函数的退出而销毁。因此,age = 22这个局部变量就消失了。 但是在js中,age = 20这个变

胡西风的博客 1436

16、天文时间序列分类:基于人工神经网络的研究

本研究探讨了基于人工神经网络的天文时间序列分类方法,重点比较了MLP、LSTM和CNN等模型在BRITE和开普勒K2数据集上的表现。研究发现LSTM不适用于此类数据,而结合特征提取与PSO超参数优化的多层感知器(MLP)在开普勒K2数据上实现了98.55%的二分类准确率。通过精细的数据预处理和高置信度样本选择,显著提升了分类性能。研究成果为恒星变异性识别提供了高效工具,并对天文学与机器学习交叉领域具有重要参考价值。

pz8901234的博客 113

也聊聊Javascript闭包(Closure)

说起闭包,记忆最深刻的莫过于初中数学老师的解释,一个包含边界的数值范围。一条数轴,两个实心点,一条括号一样的线,表示了闭包。对应的数学记号例如[1,8],包含1、8以及大于1小于8的所有数。网上有些资深人士说,Javascript的闭包就是内部函数,或者更具体点是return的内部函数。作为数学系的毕业生,直觉告诉我应该没有那么简单: 中学和大学的数学课程里面都有涉及到闭包,但都是范围概念。

永无止境,上下求索 2150

scp 出现Permission denied错误 解决方法

第一种说辞(来源于网络),说是scp涉及root远程登录,默认是没有打开的,只需要把配置文件中的permit打开即可。最后scp的时候发现还不行,只需要将其scp的服务器用户名 修改为root即可。第二种解决方案,将scp 传输的服务器用户名改为root即可。(这是最基本的,一开始我忽视了这个问题,导致一直scp不了)window系统下,向ubuntu操作系统 scp传输文件。

码农研究僧的博客 6730

AUTOSAR从入门到精通-中间件通信DDS(一)

汽车开放系统架构(automotive open system architecture,autosar)是由全球各大汽车oem、零部件供应商、汽车电子软件公司联合建立的一套标准协议。该协议规范了一个符合汽车电子软件开发的、开放的以及标准化的软件架构。最初的autosar规范的制定只考虑传统汽车电子电器架构,基于硬件算力有限场景,提供确定的功能。

getusushu的博客 1871

聊聊闭包(以JS为例)

闭包是JavaScript中的一种特性,允许函数访问和操作其外部函数的变量。定义:闭包是记住并访问外部变量的函数。功能:它们用于数据封装、状态保持和创建私有变量。实现:通过内部函数访问外部函数的变量自动形成。注意:使用时要注意避免内存泄漏。

a3098448071的博客 1254

英飞凌Tricore实战系列导读

笔者结合项目应用经验对Tricore MCU的开发及应用经验进一步总结,成人达己,渡己渡人。

initiallizer的博客 3792

聊聊JS中的闭包

闭包是什么,闭包的使用,什么是函数的词法作用,需要注意什么。提示:以下是本篇文章正文内容,下面案例可供参考。

weixin_44723417的博客 261

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

简单聊聊之JS的闭包问题

** 关于Javascript中的闭包 ** 我们优先从程序入手function makeATest(){ var test = []; for(var i=0;i<5;i++){ test[i] = function(){ return i; } } return test; } var test = m

divid11的博客 312

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

聊聊Go里面的闭包

聊聊Go里面的闭包......

秦怀杂货店 4289

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

php闭包和js闭包的区别

对于闭包的认知总觉的有点不够系统化,没有很好的认知这个东东。今天抽时间来记录一下,总结一下 php闭包和javascript 闭包的异同。 1 什么是闭包 php:你跟我聊闭包之前啊,首先来聊聊 匿名函数(Anonymous function)下面就是一个匿名函数的栗子,匿名函数 顾名思义就是没有名字啊。。 (PHP在引入闭包之前,也有一个可以创建匿名函数的函数:cr

一亩地的专栏 1724

浅谈js中的闭包

hello!大家好,我是一名正在乱学前端技术的大学生,今天聊聊JavaScript中的闭包,如有讲错的地方麻烦提出指正。

2301_76607771的博客 1320

JavaScript闭包的那些事~

JavaScript闭包 目录JavaScript闭包1.函数在JavaScript中的地位2.JavaScript中闭包的定义3.闭包是如何形成的?4.闭包的访问和执行过程5.闭包的内存泄露6.使用浏览器查看闭包 1.函数在JavaScript中的地位 在介绍闭包之前,可以先聊聊函数在JavaScript中的地位,因为闭包的存在是与函数息息相关的。 JavaScript之所以可以称之为支持头等函数的编程语言,是因为JavaScript中函数是一等公民; 函数不仅在JavaScript中扮演着重要的角

qq_52732369的博客 899

茶余饭后聊聊闭包到底是个什么东东?

闭包是我们每一个前端打工人绕不开的技能点,它经常出现在:同事之间吹水,面试官刁难时等一系列高端局中。时至今日,要是问你闭包到底是做什么的,你请答出个一二三吗?

爱勇宝 1000

聊聊前端开发中关于闭包的那点事

聊聊前端开发中关于闭包的那点事 今天老大去面试了一个两年工作经验的前端工程师,一个关于js闭包的问题直接将面试的人问懵了,我个人感觉对于一个有两年经验的前端开发人员来说,闭包应该是必须要掌握的。如果只有一年的经验,我可以理解,但是两年及以上,此处省略…。 好了不卖关子了,今天我们就来说说关于javascript的闭包。 我们从三个方面讲解 1.什么是闭包? 2.闭包有什

wang839305939的博客 2422

JavaScript篇:那些年,被我们误解的JavaScript闭包

作为前端开发必备的核心概念,闭包常常让初学者感到困惑。记得刚入行时,我也曾被各种晦涩的解释绕得云里雾里。直到在项目中踩了几个坑,才真正理解了它的精妙之处。今天,就让我们抛开教科书式的定义,用实际的代码来聊聊这个看似神秘的概念。

欢迎来到我的前端博客!这里汇集了关于前端开发的最新技术、实用工具和经验分享。我将为你提供详细的教程、代码示例和实战案例,帮助你掌握Web开发的核心概念和技能。不论你是初学者还是有经验的开发者,这个博客都适合你。 887

js 点击闭包_【JS进阶】Javascript 闭包与Promise的碰撞

最近遇到一个比较有意思的题目,解决之后深入地思考了一下。整理整理我在其中的收获,写个文章分享给大家。一等公民进入正题之前再聊聊一个话题 —— JavaScript 的一等公民在 JavaScript 这门语言中,一等公民不仅包含了 变量,对象 等这些名词性的语法,更重要的是 函数 也是一等公民!因此:函数也可以被当做参数来传递函数也可以作为函数的返回值函数也可以被赋值到某个变量函数也动态地先定义(...

weixin_39610724的博客 156

聊聊闭包和装饰器

闭包和装饰器是学习JavaScript/Python的难点,理解这两个概念是学好这类语言的基础。

weixin_39777751的博客 289
下一篇: Vue中的虚拟DOM
前端工程狮-欧YY
博客等级 码龄7年 1粉丝 3原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值