什么是闭包?
官方版
先丢一个官方的闭包定义出来:
闭包是函数和周围状态(词法环境)的组合,换句话说,闭包使你可以用内部函数访问外层函数的作用域。在JS中,每当你创建一个函数,闭包也会随之被创建。
但是在真正理解闭包之前,需要了解作用域和生存周期。
作用域
作用域就是一个东西(变量、函数、其他)起作用的范围。
局部变量只能在定义它的函数内使用,且在JS中,子函数可以直接使用父函数的局部变量
(注意var声明的变量存在变量提升的现象。)
生存周期
计算机资源有限,所以用完的东西就要尽快释放掉,也就是“垃圾回收”。
JS、Java、Python等高级语言的垃圾回收是自动回收(Garbage Collection)。需要一定的标准来进行限制,不能把可能用到的东西给回收了。
-
局部变量(通常)在函数执行后,就会被回收(其实并没有被立即回收,而是被标记为“可回收”,在下一次GC工作时被带走)
-
函数的存在,延长了外层局部变量的生存周期,只要这个函数还在,那么它外面的局部变量就不会回收
-
闭包会保留全部父级变量,不论是否用到
-
闭包的存在,不仅延长父级的局部变量有效期,父级的父级、父级的父级的父级...一直到全局的,其实都会延长
JS会进行引用数计数,一旦引用计数归零,则被标记为“可回收”。即引用计数机制,确定一个东西是否能回收。
如何自己概括闭包?
综上,我们可以自己对闭包的概念进行概括。
闭包:函数与函数外部变量组成闭包,在闭包结构中,子函数可以使用父函数的局部变量,函数的存在,延长了所有外部局部变量的存在周期。