对于闭包的一些理解

1、闭包的定义

关于闭包的定义众说纷纭,下面是一些权威给出的说法:闭包

高程3:“闭包是指有权访问另外一个函数做用域中的变量的函数”;函数

犀牛书:“函数对象能够经过做用域链相互关联起来,函数体内部的变量均可以保存在函数做用域内,这种特性在计算机科学文献中称为‘闭包’”;spa

你不知道的JavaScript(上卷):“当函数能够记住并访问所在的词法做用域时,就产生了闭包,即便函数是在当前词法做用域以外执行”。code

而我对于闭包通俗直白的我的理解是:函数定义的做用域链在函数执行后不会消失,而是由内部函数持有对这个函数的做用域的引用,这个引用就叫做闭包。对象

能够看出,闭包彻底是跟“(词法)做用域”想关联,做用域以前已作过大体介绍,以后将会再次深刻讨论(词法)做用域。blog

2、实例

var variable = "window say hello";
function localFun(){
    var variable = "localFun say hello";
    function f(){
        return variable ;
    }
    return f;
}
localFun()();

这里调用 localFun() 会返回 "localFun say hello",相信你们都已经猜到了,可是为何会返回这个结果呢?我是这样理解的:这里f()是localFun()的嵌套函数,它持有对localFun()内部做用域的引用(而这个引用就叫作闭包),这个引用捕捉到了局部变量,并一直保存了下来,因此返回的是"localFun say hello"ip

可是可能有人会以为外部函数中定义的局部变量在函数返回后就不存在了,因此localFun()的返回值应该是"window say hello"。但现实并不是如此,在js中,每次调用函数的时候,都会为之建立一个对象保存局部变量,把这个对象添加到做用域链中。当函数返回的时候,若是没有嵌套的函数,也没有其余引用指向这个绑定对象的时候,它才会被看成垃圾回收掉;而若是函数定义了嵌套的函数,并将它做为返回值返回或者存储在某处的属性里,这时就会有一个外部引用指向这个嵌套的函数,他就不会被当作垃圾回收。作用域

总结:不管经过何种手段将内部函数传递到所在的词法做用域之外,它都会持有对原始定义做用域的引用,不管在何处执行这个函数都会使用闭包。io