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

152  附录 A  JavaScript 的高级特性


             是,在 generateClosure() 调用结束后,counter() 却引用了“已经释放了的” count
             变量,而且非但没有出错,反而每次调用  counter() 时还修改并返回了 count。这是怎
             么回事呢?
                 这正是所谓闭包的特性。当一个函数返回它内部定义的一个函数时,就产生了一个闭包,
             闭包不但包括被返回的函数,还包括这个函数的定义环境。上面例子中,当函数
             generateClosure() 的内部函数 get  被一个外部变量 counter  引用时,counter 和
             generateClosure() 的局部变量就是一个闭包。如果还不够清晰,下面这个例子可以帮助
             你理解:

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

                 var counter1 = generateClosure();
                 var counter2 = generateClosure();
                 console.log(counter1()); // 输出 1
                 console.log(counter2()); // 输出 1
                 console.log(counter1()); // 输出 2
                 console.log(counter1()); // 输出 3
                 console.log(counter2()); // 输出 2
                 上面这个例子解释了闭包是如何产生的:counter1 和 counter2 分别调用了 generate-
             Closure() 函数,生成了两个闭包的实例,它们内部引用的  count 变量分别属于各自的
             运行环境。我们可以理解为,在 generateClosure() 返回 get 函数时,私下将 get 可
             能引用到的  generateClosure() 函数的内部变量(也就是  count 变量)也返回了,并
             在内存中生成了一个副本,之后 generateClosure() 返回的函数的两个实例 counter1
             和 counter2 就是相互独立的了。

             A.2.2  闭包的用途

                 1. 嵌套的回调函数
                 闭包有两个主要用途,一是实现嵌套的回调函数,二是隐藏对象的细节。让我们先看下
             面这段代码示例,了解嵌套的回调函数。如下代码是在 Node.js 中使用 MongoDB 实现一个
             简单的增加用户的功能:
   154   155   156   157   158   159   160   161   162   163   164