Js闭包总结

JS闭包总结

定义

定义
在A函数中定义一个B函数(函数的嵌套定义),在B函数中使用了A函数中的变量,就会产生闭包。具体来说,就是B就是一个闭包。

闭包的三大特点为:

 1函数嵌套函数
 内部函数可以访问外部函数的变量
 参数和变量不会被回收。

注意:
1.嵌套定义
2.引用变量

用debuuger观察闭包

下面这个简单的js函数里就构成啦闭包

我们来利用调试器看看闭包的产生
在这里插入图片描述
在这里插入图片描述
如果没有变量引用,则也不会看到闭包。

闭包的作用

何时使用

变量既想反复使用,又想避免全局污染

如何使用?

 定义外层函数,封装被保护的局部变量。
 定义内层函数,执行对外部函数变量的操作。
 外层函数返回内层函数的对象,并且外层函数被调用,结果保存在一个全局的变量中。

1 延长变量生命周期。
上面的代码中,闭包B会延长变量i的生命周期,它有能力可以让i活的更久一些。这里的i 是A的局部变量,它正常的生命周期是函数A的调用过程。
上面的代码中,闭包B会延长变量i的生命周期,它有能力可以让i活的更久一些。这里的i 是A的局部变量,它正常的生命周期是函数A的调用过程。

在这里插入图片描述

    在调用A的过程中,由于i是它的局部变量,所以A会向内存申请一个空间来放i,但当A调用结束后,这个空间会回收,即i就死了。
    
   闭包B的能力就是可以让函数A()执行完成之后,i仍然活着!!!!实现这个能力还需要有一个帮手:return !

延长变量的生命周期

在这里插入图片描述

      可以看到,每次调用r(),都可以对i的值进行++,再输出来。这就说明,A()调用之后,i 并没有死掉了,它还活着。

原因如下

还没有开始调用A()

在这里插入图片描述

 接下来,开始调用A()A函数内部,有两个局部变量:B 它还是引用类型的。要用到堆区所以A会去申请空间

在这里插入图片描述

接下来,执行return B

在这里插入图片描述

 结果如下:

在这里插入图片描述

 由于在B的函数体中用到变量i ,所以i的空间不能被回收。即i的生命周期被延长了。

再次观察调试面板:
在这里插入图片描述
由于在函数B的内部它用到它外部的变量i,在这个函数B没有死掉之前,i是不会消失的。

闭包的经典应用

经典应用1实现节流函数

在mui的buffer()函数中,我们提到了节流函数。节流函数就是一个函数在指定的时间间隔内,只能被调用一次。

例如,f函数,在1000ms内,只能调用一次。换句话,此时你调用f,则下一次再调用要等1000ms。本质上就降低函数执行的频率。

在这里插入图片描述
在这里插入图片描述
要求:1000ms内只能执行一次f.

改进如下:

在这里插入图片描述
在这里插入图片描述

上面的代码起到了降频的效果。

分析:

在这里插入图片描述

Var f = A():执行完成,

下面执行
Div.addEventListenter(“mousemove” ,f)
这一句执行之后,则如果鼠标在div上移动就会去调用f,

分析一下调用f的过程。
下面的代码就是f的函数体:
在这里插入图片描述

比较当前的时间与第一次保存的now的值之间是否>500( 表示时间过了500ms ).如果成立,则执行核心语句: Console.info(“鼠标移动中…”)

同时更新最近一次执行f的时间。Now = Date.now(); 由于now没有回收,所以它还可以正常访问的。

如果不成立(说明时间没有过500ms)

下面是一个节流函数

在这里插入图片描述

让函数只能被调用指定次数

在这里插入图片描述

在这里插入图片描述

经典应用3

在这里插入图片描述
上面点击每一个li都会输出3

解决办法 1:使用自定义属性

在这里插入图片描述
解决办法 2:使用闭包

在这里插入图片描述

 (1)iife。在function的前面有=号。
lis[i].onclick = function(index){}(i)

(2)闭包结构。

a)	function的嵌套
b)	在子函数中,用到了index,而index是父函数的形参,就相当于是父数的局部变量。所以 ,也就是在子函数中使用了父函数中定义的变量。
c)	Return 子函数。

闭包与内存泄漏

一般来说,在函数内部定义的变量,会随着函数的调用结束而被系统回收,如下:
Function f(){
Var i ;
}
F();
在F()执行完成后,i就不能再访问到了 。

由于闭包结构的存在,如下:

Function f(){
 Var i ;
 Return function(){
  Console.info( i):
}
}

Var r = f();
R();

上面的代码中,由于r()在执行时,还需要用到变量i,这个变量i并不会被系统回收。

这种情况,我们不需要手动去回收变量(如在 c中,内存空间是可以手动回收的),js中内部有垃圾回收机制去做这件事,我们不需要管。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值