javascript之什么是闭包

什么是js闭包?

Js闭包是前端面试时最常见的题目。而在实际开发过程中,也会经常因为不注意闭包而导致代码运行得不到自己想要的结果。

想要掌握闭包,就必须了解javascript中的变量作用域。

Javascript中的变量根据作用域分为两种:全局变量和局部变量。

全局变量就是在文档最外层声明的,在全文当中都可以读取的变量。

局部变量就是在函数内部声明的,只在该函数内部可以读取的变量。

值得注意的是,在函数内部,可以读取与使用在函数外部声明的全局变量。

 

javascript之什么是闭包

以上代码运行结果为:

 javascript之什么是闭包

a是全局变量。b是局部变量。注意,如果在声明变量时,不管你是在函数内部或者函数外部,不使用关键字var,那么这个变量都默认为全局变量。

在函数外部无法读取函数内部的变量:

 javascript之什么是闭包

以上代码运行结果为:

 javascript之什么是闭包

如果我们偏要在函数外部读取函数内部的局部变量怎么办?你可以这么做:

 javascript之什么是闭包

我在fun1函数内部再次声明一个函数fun2,根据变量作用域的特点,我在fun2内,是可以访问到fun1内声明的变量的,但反过来,在fun2内声明的变量,对于fun1来说是不可见的(javascript中的链式作用域)。而之后我将fun2当做fun1的运行结果return出去。在fun1外部用一个参数result接受这个结果,再运行,此时,result()就相当于fun2(),所以上面的代码运行结果是:

 javascript之什么是闭包

利用这种取巧的方法,我就可以在fun1外部读取到fun1内部的局部变量b的值了。

其实,上面的fun2就是一个闭包。

所以,我的理解是,闭包就是能够读取其他函数内部变量的函数,也就是说,凡是定义在函数内部的函数,都可以看做是一个闭包。闭包就是将函数内部环境与函数外部环境链接起来的一座桥梁。

知道了什么是闭包,我们再来看看闭包有什么用?

一般在开发中,闭包主要有两个作用:1、读取其他函数内部的变量。2、让某个函数的变量一直保存在内存中。

第一个作用我们就不用再解释了,直接来看第二个作用,如下图:

 javascript之什么是闭包

以上代码的运行结果为:

 javascript之什么是闭包

第一次执行result(),调用fun2()b++,并打印b,结果为2。这相信大家都很清楚。但在第二次执行result()的时候,打出的结果却变成了3,这说明,在第一次执行result()之后,fun1内的变量b被该成了2,并且该变量b一直保存在内存中,没有在fun1()执行后被回收。当第二次执行result()的时候,变量b再次加1,变为了3

Why?这是因为fun1()在执行的结果是返回了fun2,我们又把fun1()的执行结果赋给了一个全局变量result,也就是把fun2赋给了result,这导致fun2始终在内存中,不会被回收。而fun2的存在又依赖于它的父函数fun1,所以fun1也会一直在内存中,不被回收,最终就导致了fun1内的变量b也不被垃圾回收机制回收。

最后,在开发中使用闭包的时候我么应该要注意些什么呢?

1、由于闭包内的变量不会被垃圾回收机制回收,这就大大的占用了内存资源,容易导致内存泄露。所以在使用闭包后,应该手动删除不需要的局部变量。
2、闭包会改变父函数内的变量,如果该变量是静态的,私有的,那么一定要小心使用。