目录
- 变量作用域
- 闭包的概念
- 闭包的用途
- 闭包的缺点
- 最后总结一下闭包的好处与坏处
- 总结
变量作用域
要理解JavaScript闭包,就要先理解JavaScript的变量作用域。
变量的作用域有两种:全局的和局部的(全局变量和局部变量)
JavaScript中,在函数内部可以直接读取到全局变量。
var n=10 function fn(){ alert(n) } fn() //10
而在函数外部无法读取到函数内部的变量。
function fn(){ var n=10; } fn() alert(n) //n is not defined 函数外部无法读取到函数内部的n
注意:函数内部使用var声明变量的时候,这个变量是局部变量,如果不使用var,那么这个变量就是一个全局变量。
例如:
function fn(){ n=10; } fn() alert(n) //10
另外,函数的参数也是局部性的,只在函数内部起作用。
在正常情况下,我们是无法得到函数内部的局部变量的,只有变通方法才可以——在函数内部再声明一个函数。
function f1(){ var n=10; function f2(){ alert(n) } }
f2函数可以得到f1函数内的所有局部变量,但是f1函数却无法得到f2函数内部的局部变量——JavaScript语言特有的“链式作用域”结构。(即子对象会一级一级地向上寻找所有父对象的变量),所以,父对象的所有变量,对于子对象都是可见的。
f2函数可以获取到父级函数f1的局部变量,那么如果把f2()函数返回,在函数f1外部就可以访问到f1()函数内部的变量了。
例如:
function f1(){ var n=10; function f2(){ alert(n) } return f2() } f1() //页面弹出10
例子中的f2()函数就是一个闭包函数。
闭包的概念
由于作用域原因,我们无法在函数外访问函数里面定义的变量,但有事我们又有这个需求,因此就出现了闭包的概念。
闭包是指有权访问另一个函数作用域中的变量的函数。
在上面的例子中,内部函数f2就是一个闭包函数。
在本质上,闭包就是将函数内部和函数外部连接起来的桥梁。
闭包是一种保护私有变量的机制,在函数执行时形成私有的作用域,保护里面的私有变量不受外界干扰。
闭包的用途
(1)可以读取父级作用域函数内部的变量;
(2)让变量的值始终保存在内存中(让局部变量变成全局变量),不被垃圾回收机制清除。
闭包的缺点
由于闭包会使函数中的变量都保存到内存中,垃圾回收机制不清理,内存消耗很大,所以不能滥用闭包,否则可能导致内存泄漏。
补充:
什么是内存泄漏?
程序的运行都是需要内存的。只要对内存提出要求,操作系统必须供给内存。
当应用程序中的一些代码变量不再需要用到内存时,但是没有被操作系统或者可用内存池回收,就说明它发生了内存泄漏。
即,当已经不再需要某块内存时,这块内存还存在着——内存泄漏
解决闭包引起的内存泄漏的问题:
在退出函数之前,将不使用的局部变量全部删除。
例如:将当前变量的值设置为‘null’,当垃圾回收机制启动时,会自动对这些值为‘null’的变量回收。
最后总结一下闭包的好处与坏处
好处
①保护函数内的变量安全 ,实现封装,防止变量流入其他环境发生命名冲突
②在内存中维持一个变量,可以做缓存(但使用多了同时也是一项缺点,消耗内存)
③匿名自执行函数可以减少内存消耗
坏处
①其中一点上面已经有体现了,就是被引用的私有变量不能被销毁,增大了内存消耗,造成内存泄漏,解决方法是可以在使用完变量后手动为它赋值为null;
②其次由于闭包涉及跨域访问,所以会导致性能损失,我们可以通过把跨作用域变量存储在局部变量中,然后直接访问局部变量,来减轻对执行速度的影响
总结
到此这篇关于JavaScript闭包函数的文章就介绍到这了,更多相关JavaScript闭包函数内容请搜索NICE源码以前的文章或继续浏览下面的相关文章希望大家以后多多支持NICE源码!