这三天都在看JavaScript的闭包,终于有点眉目了。

动力

去年在看《黑客与画家》的时候,被里面对不同编程语言描述能力的差异所吸引。
里面描述了if-else、函数递归、闭包、宏等多个语言的抽象层次。
既然闭包是语言的一种重要抽象,我决心要弄清楚是怎么回事。

方法

从JavaScript入手,是因为对js的基础语法还比较熟悉,从这里开始看起容易接受。
按照网上的说法,犀牛书(《JavaScript权威指南》)介绍js的闭包非常清晰易懂,我就从此书看起。主要就看了第四章变量和第八章函数。
但是闭包的最后一个例子不能理解,于是又搜到了一个书评,这个解释很受启发。
另外还有所谓闭包.pptx,这个只是浏览了一下。

认识

花了三天时间,回想起来,从看js的变量作用域,到理解函数作为一个对象,可以被随意传递从而发生的各种“匪夷所思”的事,对闭包逐渐有了脉络。
现在觉得闭包这个称呼也很贴切:一个函数带上它周围的变量包成一团封起来(不过一般习惯上这个函数就叫闭包了,并没把附带周围的变量叫到一起……)。里面的变量逃不出去,不会污染外面的变量名;外面也没法攻入,垃圾回收不能随意收回里面的变量。这团闭包还独立地存在着,携带着里面的东西,帮着别的对象完成一些功能。
犀牛书的前两个例子就是说明了外面没法直接访问闭包内的变量,必须通过指定的方法来访问。相当于class中定义了private的变量。但是这里并不像C++那样,让编译器去识别某个变量外部能不能访问,而是直接通过语言本身的特性,让外面没法访问到。这种设计让语言更为精巧。
第三个例子是利用了闭包可以携带周围变量,构造了一个调试工具。

虽然自认为理解了闭包的原理,不过到灵活运用还有很长的路要走。推崇lisp的人鼓励使用闭包,现在还很难理解那种函数式变成的思考方式。期待有时间进一步学习更抽象的语言。