- 闭包 closure(理解 加分项)
10.1. 闭包定义closure
定义:
在函数f的内部又定义了函数f1
并且f1还使用了f的局部变量
说f1是一个闭包,或者说,这里形成一个闭包的结构。
10.2. 延长变量的生命周期
改进一下代码:
说明:
(1)var a = 0 ;变量a是函数f()的局部变量
(2)F1是定义 在f内部的函数,所以它能够访问a。
(3)第24行结束后,相当于是f调用完成。
(4)第28-31行,我们能还可以通过r 访问a这个变量。
这个例子当中 ,但f被调用完成后,其中变量a仍然可以被访问,换句话,f的局部变量在结束f的调用后,没有被回收!
对于变量a而言,正常情况下:因为这是一个局部变理,它只能在存在于第12-22行。
这个例子中,我们通过一个闭包结构,让它的生命周期延长了,现在在f()的外部也可以访问a。当然,这个访问是间接的,不能直接console.info(a)。
10.3. 通过debugger查看
10.4. 图示
10.5. 例子
(1)为什么是5?
Lis.length = 5;
对于for循环,当i = 5时,结束循环。所以这个值是5.
(2)为什么总是5?
当整个for循环结束后,用户才可能去通过点击鼠标去触发onclick事件。
换句话说:for执行在前面;然后才是事件响应函数执行。
当for循环完成后,这个i就是5 。所以你每次点击都是5.
10.5.1. 解决方法 1
10.5.2. 解决方法 2
(1)闭包:function(){console.info(index)} 就一个闭包。满足:
a.它定义在立即执行的函数表示式内部。相当于在函数的内部定义了一个函数。
b.它用到了父级函数的局部变量index.
(2)带参数的立即执行函数表达式。
形参是index.实参是i.
把i的值传递到index中。
调试
10.6. 缺点:闭包会产生内存泄漏
第24行结束后。
全局代码:我调用了f()把结果保存在r中,我准备要求函数f把它自己定义的变量a,f1删除。
r说:不行!你不能不删除!。我要用f1.
全局代码: 我让f把a给删除了?
r说:不行,因为f1要用a!
全局代码:我不管了。反正f我已经调用完了。我下班了。
第28行:
r()执行完后,我没有创建任何变量, 我不能做回收的工作,我也下班了。
。。。。。。。
a,f1没有人管了。它们会一直存在,直到这个html文件关闭。
10.7. 总结
你要正确地使用闭包:
(1)可以不用就尽量不用。
(2)你一定要去理解它的原理,能够正确的写出闭包结构。
10.8. 问题
10.8.1. f()()与r()的区别
F()() :先执行f()。Var a = 0 ,然后再执行f1(),a = a+1。所以结果a = 1;
F()() : 先执行f()。Var a = 0 ,然后再执行f1(),a = a+1。所以结果a = 1;