Page 158 - Node.js开发指南
P. 158

附录 A  JavaScript 的高级特性    151


                    任何地方隐式定义的变量(未定义直接赋值的变量)。                                                         1
                   需要格外注意的是第三点,在任何地方隐式定义的变量都会定义在全局作用域中,即不
               通过 var 声明直接赋值的变量。这一点经常被人遗忘,而模块化编程的一个重要原则就是
               避免使用全局变量,所以我们在任何地方都不应该隐式定义变量。
                                                                                                      2
               A.2 闭包


                   闭包(closure)是函数式编程中的概念,出现于 20 世纪 60 年代,最早实现闭包的语言
               是 Scheme,它是 LISP 的一种方言。之后闭包特性被其他语言广泛吸纳。                                                3
                   闭包的严格定义是“由函数(环境)及其封闭的自由变量组成的集合体。”这个定义对
               于大家来说有些晦涩难懂,所以让我们先通过例子和不那么严格的解释来说明什么是闭包,
               然后再举例说明一些闭包的经典用途。
                                                                                                      4
               A.2.1  什么是闭包

                   通俗地讲,JavaScript  中每个的函数都是一个闭包,但通常意义上嵌套的函数更能够体
               现出闭包的特性,请看下面这个例子:                                                                      5


                   var generateClosure = function() {
                     var count = 0;
                     var get = function() {
                       count ++;                                                                      6
                       return count;
                     };
                     return get;
                   };
                                                                                                      7

                   var counter = generateClosure();
                   console.log(counter()); // 输出 1
                   console.log(counter()); // 输出 2
                   console.log(counter()); // 输出 3
                                                                                                      8
                   这段代码中,generateClosure() 函数中有一个局部变量count,初值为 0。还有一
               个叫做 get 的函数,get 将其父作用域,也就是 generateClosure() 函数中的 count 变
               量增加 1,并返回 count 的值。generateClosure() 的返回值是 get 函数。在外部我们
               通过 counter 变量调用了 generateClosure() 函数并获取了它的返回值,也就是 get 函                               9
               数,接下来反复调用几次 counter(),我们发现每次返回的值都递增了 1。
                   让我们看看上面的例子有什么特点,按照通常命令式编程思维的理解,count 是
               generateClosure 函数内部的变量,它的生命周期就是 generateClosure 被调用的时
               期,当 generateClosure 从调用栈中返回时,count 变量申请的空间也就被释放。问题                                     10
   153   154   155   156   157   158   159   160   161   162   163