你不知道的JavaScript(三)闭包

来源:互联网 发布:爱淘宝流氓软件 编辑:程序博客网 时间:2024/05/18 04:39

闭包是什么

函数即使在当前词法作用域外执行,也能够记住并访问函数定义所在的词法作用域,这就是闭包。(该定义来自于《你不知道的JavaScript》上卷,推荐阅读英文原版,中文版翻译不太准确)
对词法作用域不了解的可以阅读《你不知道的JavaScript》上卷第二章。
举个例子:

function foo() {    var a=2;    function bar() {        console.log(a);    }    return bar;}var baz=foo();baz();//2

首先分析上述代码做了什么:
函数bar()的词法作用域能够访问foo()的内部作用域,bar()函数本身被当做了一个值进行传递。
foo()执行后,返回值bar()函数赋值给了变量baz,然后调用了baz()

上述过程的实质其实就是通过不同的标识符(foo()baz())引用调用了内部的函数bar(),它在自己的词法作用域(foo()内部)以外的地方(全局作用局)执行,但是依旧可以访问其所在的词法作用域(依然可以访问变量a),这就是闭包。

foo()执行完毕后,通常foo()的整个内部作用域会被销毁,因为引擎有垃圾回收机制来释放不再使用的内存空间。由于看上去foo()的内容不会再被使用,所以自然要对其进行回收。
但是闭包会阻止这件事的发生。事实上,bar()保持着对内部作用域的访问权限,所以内部作用域依旧处于使用状态,因此不会被销毁。

不论对函数类型的值以何种方式进行传递,只要函数能在别处被调用,就会产生闭包。例如:

function foo() {    var a=2;    function baz() {        console.log(a);    }    bar(baz);}function bar(fn) {    fn();}

上述代码将内部函数baz传递给bar,当调用这个内部函数时,它能够访问a,这也是闭包。

原创粉丝点击