JS闭包

闭包是JavaScript中函数的一种高级应用方式,学起来有点复杂,所以想弄懂js闭包,我们需要先了解一下函数的两个阶段(定义阶段和调用阶段)。定义阶段1、在内存中开辟一个存储空间2、把函数内的代码当做字符串一模一样地放在这个空间中(所有变量都不进行解析)3、把这个空间地址赋值给函数名(变量名)调用阶段:1、按照函数名(变量名)找到对应的存储空间2、重新开辟一个函数执行空间3、在执行空间里进行形参赋值4、在执行空间里进行预解析5、把函数存储空间的代码复制一份到执行空间里面执行一遍6、执行完毕之后,执行空间销毁如下图所示: 函数的两个阶段 在特殊情况下,会出现一个不会销毁的函数执行空间——就是当函数内部返回一个复杂数据类型,并且在函数外部有变量接收这个复杂数据类型,这个时候函数的执行空间不会被销毁;当外部接收的这个变量不再引用函数内部的返回值时,这个函数空间就销毁了(如下图所示)。 一个不会销毁的函数执行空间 弄懂函数这些知识点之后,再来学闭包就不难了。首先,形成闭包要符合这三个条件,而且三者缺一不可:1、函数A内部直接或间接返回一个函数B2、B函数内部使用着A函数的私有变量3、A函数外部有一个变量接收B函数 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 的值 这里面会涉及到一些概念:我们把这个不会销毁的A函数的执行空间叫做“闭包空间”;把A函数里面返回的B函数叫做“A函数的闭包函数”;所以闭包的官方定义也指函数内部的函数。接着说一下闭包主要的三个特点:1、延长了变量的生命周期;这个特点的好处就是变量会一直存在,但是因此也成了一个致命的缺点:就是这个函数的执行空间不会被销毁,而当一段内存空间中有一个不会被销毁的东西一直存在,就会出现内存占用,如果过多的话,还会导致内存溢出,结果引起内存泄漏。2、可以访问函数内部的私有变量;利用这个特点,我们可以在函数外部访问到内部的数据。3、保护私有变量;这是所有函数都具备的特点之一,普通函数的内部变量是不能在外部访问的,但是闭包空间可以。可以借助这张图片进行理解: 闭包 了解了闭包的特点之后,我们就可以在需要延长变量声明周期的时候,或者需要访问某个函数内部私有数据的时候,用闭包函数来解决问题啦,比如:循环绑定事件。 循环绑定事件 需要注意的是,闭包虽然有好处,但是如果我们有其他办法,还是尽量不要使用闭包函数,因为它的缺点是致命的哟!(慎用)

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):