什么是闭包?
闭包的本质就是在一个函数内部创建另一个函数。
闭包的作用、意义?
根据作用域链我们可以知道,在js环境中访问变量是由内向外的,内部作用域可以访问当前作用域下的变量和外层作用域下的变量,反之则不能,也就是说在外层作用域下无法获取内层作用域下的变量,同样在不同的函数作用域中也是不能相互访问彼此变量的,那么我们想在一个函数内部也有限权访问另一个函数内部的变量该怎么办呢?闭包就是用来解决这一需求的。
闭包的特性?
- 函数嵌套函数
- 函数内部可以引用函数外部的参数和变量
- 参数和变量不会被垃圾回收机制回收
闭包的两种形式
1、函数作为返回值
如图所示,匿名函数访问外层title变量,并作为返回值返回给了函数Zpy,又赋值给了全局下的变量sj。
闭包产生的问题:
一般情况下,在函数Zpy执行完后,就应该连同它里面的变量一同被销毁,但是在这个例子中,匿名函数作为Zpy的返回值被赋值给了sj,并且匿名函数内部引用着fn里的变量num,所以变量title无法被销毁,就产生了内存消耗的问题。
解决的办法:将不再使用的变量赋值为null
2、闭包作为参数传递
如图所示:
函数zpy被作为参数传递到立即执行函数sj中,此时,由于函数中的自由变量,取决于函数定义的地方,跟执行的地方没关系,所以函数zpy中n的取值是全局范围下的15,而不是100。
闭包的优、缺点
优点
①保护函数内的变量安全 ,实现封装,防止变量流入其他环境发生命名冲突
②在内存中维持一个变量,可以做缓存(但使用多了会导致消耗内存)
③匿名自执行函数可以减少内存消耗
缺点
- 被引用的私有变量不能被销毁,增大了内存消耗,造成内存泄漏,解决方法是可以在使用完变量后手动为它赋值为null。
- 其次由于闭包涉及跨域访问,所以会导致性能损失,我们可以通过把跨作用域变量存储在局部变量中,然后直接访问局部变量,来减轻对执行速度的影响