关于JS的闭包

来源:互联网 发布:腹黑兔的逆向工程知乎 编辑:程序博客网 时间:2024/05/02 00:28

对于闭包的理解

参考链接:http://www.jb51.net/article/24101.htm

1.闭包是一种现象,一种本该销毁的局部变量却在内存中驻留的现象

形成闭包需要满足条件:

①内部函数f2在父函数f1之外被引用(如下例中f2被result引用)


上述代码中f1被调用完毕后,其内部变量n会保留在内存中,因为n被其内部函数f2引用,而f2又在f1函数外部被引用了。

result指向f2,而f2依赖于f1存在,因此f1对象的变量会保留在内存中,而不是在函数被调用后即销毁。


2.闭包也可以理解为一种特殊的函数,是在其父函数外被引用的内部函数(如例子中的fun2)。闭包是连接函数内部和外部的桥梁


在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次的值是999,第二次的值是1000。这证明了,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。

为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。

这段代码中另一个值得注意的地方,就是“nAdd=function(){n+=1}”这一行,首先在nAdd前面没有使用var关键字,因此 nAdd是一个全局变量,而不是局部变量。其次,nAdd的值是一个匿名函数(anonymous function),而这个

匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。

3.使用闭包需要注意的问题

①闭包会使函数中的变量保存的内存中,内存消耗很大,不能滥用,在IE中可能导致内存泄漏。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

②闭包会在父函数外部,改变父函数内部变量的值。使用时要小心是否改变了父函数内部变量的值。

例子1


这里obj.getNameFunc( ) 是调用fun1函数,fun1函数的返回值是匿名函数fun2,因此obj.getNameFunc( ) 等价于fun2

那么obj.getNameFunc( ) ()就是调用fun2,等价于fun2();执行的结果是返回this.name

匿名函数fun2是fun1的闭包,当其内部出现name时,首先会查找自身是否有局部变量name,然后看其父函数fun2是否包含name变量,最后看有没有叫做name的全局变量。因此return this.name 写成 return name 将得到一样的结果。

4.闭包的最主要的作用是在内存中维持一个变量

例子2


5.js中的垃圾回收机制

        在Javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收。如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。因为函数fn1被fn2引用,fn2又被fn1外的result引用,这就是为什么函数fn1执行后不会被回收的原因。

0 0
原创粉丝点击