1、闭包的概念
闭包就是能够读取其他函数内部变量的函数。
在javascript中,只有函数内部的子函数才能读取局部变量,所以说,闭包可以简单理解成“定义在一个函数内部的函数“。
本质上,闭包是将函数内部和函数外部连接起来的桥梁。
定义在一个函数内部的函数它可以读取父级函数的所有局部变量;
闭包就是在函数的“堆栈”返回后并不释放,也可以理解为这些函数堆栈并不在栈上分配而是在堆上分配。当在一个函数内定义一个函数就会产生闭包。
2、闭包的作用
一是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中,不会在调用后被自动清除。
所有的变量,如果不加上 var 关键字,则默认的会添加到全局对象的属性上去,这样的临时变量加入全局对象有很多弊端。
比如:别的函数可能误用这些变量;造成全局对象过于庞大,影响访问速度(因为变量的取值是需要从原型链上遍历的)。除了每次
使用变量都是用 var 关键字外,在实际情况下经常遇到这样一种情况,函数只需要执行一次,其内部变量无需维护,可以用闭包。
这样就会遇到不被垃圾回收机制清除的缓存问题:我们开发中会碰到很多情况,设想我们有一个处理过程很耗时的函数对象, 每次
调用都会花费很长时间,此时就需要将计算出来的值存储起来,当调用这个函 数的时候,首先在缓存中查找,如果找不到,
则进行计算,然后更新缓存并返回值,如果找到了,直接返回查找到的值即可。闭包正是可以做到这一点,因为它不会释放外部的引用,
从而函数内部的值可以得以保留。
3、闭包形成的条件
函数的嵌套
内部函数引用外部函数的局部变量,延长外部函数的变量生命周期
4、闭包的优点
(1)逻辑连续,当闭包作为另一个函数调用参数时,避免脱离当前逻辑而单独编写额外逻辑。
(2)方便调用上下文的局部变量。
(3)加强封装性,是第2点的延伸,可以达到对变量的保护作用。
5、闭包的缺点
(1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中
可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
(2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method)
,把内部变量当作它的私有属性(private value),此时就要注意不能随便改变父函数内部变量的值。
6、闭包的特性
(1)作为函数变量的一个引用。当函数返回时,其处于激活状态。
(2)闭包就是当一个函数返回时,并没有释放资源的栈区。
7、闭包对页面的影响
通过使用闭包,我们可以做很多事情。比如模拟面向对象的代码风格;能更简洁的表达出代码;在某些方面提升代码的执行效率。
8、闭包的工作原理
因为闭包只有在被调用时才执行操作,所以它可以被用来定义控制结构。多个函数可以使用同一个环境,这使得他们可以通过改变那个环境相互交流。
9、使用场景
(1)采用函数引用方式的setTimeout调用。
(2)将函数关联到对象的实例方法。
(3)封装相关的功能。