如何理解掌握闭包函数

在理解js闭包函数之前我们应该先要了解什么是js函数?

js函数中可以分为两个阶段:

函数定义阶段
1. 在内存中开辟一个存储空间
2. 把函数体内的代码当作字符串一摸一样的放在这个空间中
=> 碰到的所有变量都不进行解析
3. 把这个空间地址赋值给函数名(变量名)
=>函数调用阶段
1. 按照函数名(变量名)找到对应的存储空间
2. 重新开辟一个函数 执行空间
3. 在这个执行空间里面进行形参赋值
4. 在这个执行空间里面进行预解析
5. 把函数存储空间的代码复制一份到执行空间里面执行一遍
6. 执行完毕之后, 这个开辟出来的执行 空间销毁

注:在特殊情况下函数执行完毕,新开辟出来的空间也不会销毁
如下面这段代码函数的执行空间就不会销毁

function fn() {
      var num = [1, 2, 3]
      // 返回了一个复杂数据类型
      return num
}
  var res = fn()

上面这段代码 :

res 接受的就是 函数fn 返回的那个复杂数据类型(一个数组)
res 接受的是 函数fn 执行空间里面那个数组的地址
既res 接受的是 函数fn 的执行空间内的一个数组
+ 只要这个数组还存在, 就表示这个函数执行空间没有销毁
+ 因为一旦函数执行空间销毁了, 那么这个数组也就没有了
+ 所以这个函数执行空间不能销毁
注:当需要销毁这段空间的时候需要手动设置 res=null

回到正题:了解闭包函数

=> 闭包的生成有三个必要条件(缺一不可)
      1. 在函数 A 内部直接或者间接返回一个函数 B
      2. B 函数内部使用着 A 函数的私有变量(私有数据)
      3. A 函数外部有一个变量接受着函数 B(A函数把B函数当做返回值)
      : 形成了一个不会销毁的函数空间

闭包空间
+ 现在我们管这个不会销毁的 a 函数的执行空间叫做 闭包空间
+ 把函数 a 里面返回的 函数 b, 叫做函数a 的 闭包函数
+ 官方给的定义有一句话: 闭包 => 函数内部的函数

如下面这段代码: 函数作为返回值

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

在这段代码中,A()中的返回值是一个函数B(),这个函数在A()作用域内部,所以它可以获取A()作用域下变量num的值,将这个值作为返回值赋给全局作用域下的变量res,实现了在全局变量下获取到局部变量中的变量的值.

再来看一个闭包的经典例子:

 function fn() {
        var num = 5
        return function B() {
            var n = 0
            console.log(++n)
            console.log(++num)
        }
    }
    var res = fn()
    res() //1 6
    res() //1 7

一般情况下,在函数fn执行完后,就应该连同它里面的变量一同被销毁,但是在这个例中,函数B()作为fn的返回值被赋值给了res,这时候相当于res=B(){var n = 0 … },并且函数B()内部引用着fn里的变量num,所以变量num无法被销毁,而变量n是每次被调用时新创建的,所以每次res()执行完后它就把属于自己的变量连同自己一起销毁,于是乎最后就剩下孤零零的num,于是这里就产生了内存消耗的问题.

综上所诉利弊问题:

利:1、保护函数内的变量安全 ,实现封装,防止变量流入其他环境发生命名冲突
2、在内存中维持一个变量,可以做缓存(但使用多了同时也是一项缺点,消耗内存)
3、匿名自执行函数可以减少内存消耗
弊:1、有一点上面已经有体现了,就是被引用的私有变量不能被销毁,增大了内存消耗,造成内存泄漏,解决方法是可以在使用完变量后手动为它赋值为null;
2、其次由于闭包涉及跨域访问,所以会导致性能损失,我们可以通过把跨作用域变量存储在局部变量中,然后直接访问局部变量,来减轻对执行速度的影响

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值