闭包的生命周期与闭包存在的关键点
闭包产生的时间点
先来看一段代码(1)
上述代码中,js引擎执行它们的时候,先将fn的定义执行了(函数提升),再来到第8行执行fn,之后进入第1行,再进行函数内部的函数提升,fn1被提前定义了,即内部嵌套函数的定义在第3行执行之前被执行完毕,此时闭包产生了
闭包存在的关键点
再来看一段代码(2)
相对于代码1,代码2返回了fn1并让设定了一个变量f来接受fn返回的值(fn1函数),这两步就是闭包在执行完fn之后仍然存在的关键点,如果使用代码1,那么js引擎在执行完fn1之后(第10行),fn1在栈内存中保存了fn1内存地址的变量(如fn1:0x123)所占用的内存就会立刻被释放,随即堆内存中的fn1对象就变成了垃圾对象,很快fn1就会被js引擎中的垃圾回收器回收,因为闭包存在于fn1中,所以闭包也会随之消失。
所以此处使用f接受fn返回的fn1函数,目的就是让f也保存fn1的内存地址,这样在fn1执行完之后,即使fn1本身的栈内存被释放掉,fn1也不会成为垃圾对象被回收,因为仍然有变量引用(保存)了它,从而维持了闭包的存在
闭包的死亡
再来看一段代码(3)
在执行完11行的f(即fn1)函数后,12行将f赋值为null,这一步使得fn1成为一个空对象(垃圾对象),此时闭包死亡,如果在使用完闭包之后不让闭包死亡,那么有可能出现内存泄漏的问题,此处我就不再赘述了
综上全文
闭包的生命周期大体分两步
1.产生于嵌套的内部函数定义执行完时
2.死亡于包含闭包的对象成为垃圾对象时
闭包存在的关键点
1.使用一个变量接受嵌套的内部函数,让它在执行完之后不会成为垃圾对象,闭包从而得以存在