什么是闭包
闭包是一种组合,一个函数和该函数对它周围状态(词法环境)的引用捆绑在一起,就形成了闭包
也就是说,闭包由两部分组成:1.执行上下文;2.在该执行上下文中创建的函数
也可以说,闭包是由函数以及声明该函数的词法环境组合而成的
考虑下面这个例子:
1 | function fun() { |
在上面的例子中,我们在函数fun里定义了一个函数fn,函数fn可以访问声明于它外部作用域的变量name。而事实上,我们也通过了函数fn来访问了外部作用域中的变量name,这时候,闭包就产生了。在这个例子中,闭包=函数fn+fn对它外部作用域的引用
闭包的特点
在js中,当一个值在内存中失去其他值对它的引用时,该值会被js的自动垃圾回收机制所释放。js函数中,一个函数执行上下文的生命周期在该函数执行完毕后就结束了,该执行上下文便会被回收释放,然而闭包的存在会阻止这一行为
还是之前的例子:
1 | function fun() { |
一般来说,函数中的变量仅存在于该函数执行期间,一旦fun执行完毕,name变量应该无法再被访问,而在这个例子中,name属性仍能被访问
原因在于,该例子中形成了闭包,闭包包含了fn函数和fn的词法作用域。在该例子中,res是执行fun函数时创建的fn函数实例的引用,由于fn维持了一个对它的词法环境的引用,因此,当res调用时,name变量仍然可用
闭包的作用
通过闭包,我们可以在其他的执行上下文中,访问到函数的局部变量
闭包中变量的值始终保持在内存中
使用闭包的注意点
由于闭包中的变量始终保持在内存中,因此内存消耗会比较大,所以不能滥用闭包