聊聊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. 保护私有变量(只要是函数, 就有这个特点)
    优点: 保护私有变量不被外界访问
    缺点: 如果向访问, 必须要利用闭包函数

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

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值