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

附录 A  JavaScript 的高级特性    149


               作用域是通过函数来定义的,在一个函数中定义的变量只对这个函数内部可见,我们称为函                                               1
               数作用域。在函数中引用一个变量时,JavaScript 会先搜索当前函数作用域,或者称为“局
               部作用域”,如果没有找到则搜索其上层作用域,一直到全局作用域。我们看一个简单的
               例子:
                                                                                                      2
                   var v1 = 'v1';

                   var f1 = function() {
                     console.log(v1); // 输出 v1
                   };                                                                                 3
                   f1();

                   var f2 = function() {
                     var v1 = 'local';
                     console.log(v1); // 输出 local
                   };                                                                                 4
                   f2();
                   以上示例十分明了,JavaScript  的函数定义是可以嵌套的,每一层是一个作用域,变量
               搜索顺序是从内到外。下面这个例子可能就有些令人困惑:
                                                                                                      5
                   var scope = 'global';

                   var f = function() {
                     console.log(scope); // 输出 undefined
                     var scope = 'f';                                                                 6
                   }
                   f();
                   上面代码可能和你预想的不一样,没有输出 global,而是undefined,这是为什么呢?
               这是 JavaScript 的一个特性,按照作用域搜索顺序,在 console.log 函数访问 scope 变                               7
               量时,JavaScript  会先搜索函数 f 的作用域,恰巧在 f 作用域里面搜索到 scope 变量,
               所以上层作用域中定义的 scope 就被屏蔽了,但执行到 console.log 语句时,scope 还
               没被定义,或者说初始化,所以得到的就是 undefined 值了。
                                                                                                      8
                   我们还可以从另一个角度来理解:对于开发者来说,在访问未定义的变量或定义了但没
               有初始化的变量时,获得的值都是  undefined。于是我们可以认为,无论在函数内什么地
               方定义的变量,在一进入函数时就被定义了,但直到  var 所在的那一行它才被初始化,所
               以在这之前引用到的都是 undefined 值。(事实上,JavaScript 的内部实现并不是这样,未                                   9
               定义变量和值为 undefined 的变量还是有区别的。)
                   函数作用域的嵌套
                   接下来看一个稍微复杂的例子:
                                                                                                      10
   151   152   153   154   155   156   157   158   159   160   161