JavaScript 【函数表达式】模仿块级作用域

以下大部分为学习《JavaScript 高级程序设计》(第 3 版) 所做笔记。

  JS 没有块级作用域的概念,在块语句中创建的变量,实际上是在包含函数中而非语句中创建的。

  看下面的语句,在 fn() 中定义了一个 for 循环,如果是在 Java、C++等语言中,循环结束后 变量 i 就会被销毁。可是在 JS 中,变量 i 是定义在 fn() 的活动对象中的,因此从它有定义开始,就可以在函数内部随处访问它。

 1 <script>
 2     function fn( count ){
 3         for( var i=0; i<count; i++ ){
 4             console.log( i );
 5         }
 6         console.log( i );
 7     }
 8     fn( 2 );
 9 /*输出:
10 0
11 1
12 2
13 */
14 </script>

  JS 从来不会告诉你是否多次声明了同一个变量,如果错误地重新声明同一个变量,也不会改变变量的值,遇到这种情况,它只会对后续的声明视而不见。

 1 <script>
 2     function fn( count ){
 3         for( var i=0; i<count; i++ ){
 4             console.log( i );
 5         }
 6         var i;  //重新声明变量
 7         console.log( i );
 8     }
 9     fn( 2 );
10 /*输出:
11 0
12 1
13 2
14 */
15 </script>

  如果想要模仿块级作用域,可以使用匿名函数。

  (立即执行函数相关的笔记:https://www.cnblogs.com/xiaoxuStudy/p/12354095.html#IIFE

 1 <script>
 2     function fn( count ){
 3         //使用立即执行函数
 4         (function(){
 5             for( var i=0; i<count; i++ ){
 6               console.log( i );
 7         }
 8         })();
 9         console.log( i );   //导致一个错误。报错:Uncaught ReferenceError: i is not defined at fn
10     }
11     fn( 2 );
12 </script>

  上面在 for 循环外部插入了一个私有作用域。在匿名函数中定义的任何变量,都会在执行结束时被销毁。因此,变量 i 只能在循环中使用,使用后即被销毁,而在私有作用域中能够访问变量 count,是因为这个匿名函数是一个闭包,它能够访问包含作用中的所有变量。这种做法可以减少闭包占用的内存问题,因为没有指向匿名函数的引用。只要函数执行完毕,就可以销毁其作用域链了。

  这种技术经常在全局作用域中被用在函数外部,从而限制向全局作用域中添加过多的变量和函数。一般来说,应该少向全局作用域中添加变量和函数。在一个由很多开发人员共同参与的大型应用程序中,过多的全局变量和函数很容易导致命名冲突。通过创建私有作用域,每个开发人员既可以使用自己的变量,又不用担心搞坏全局作用域。

  

  

原文地址:https://www.cnblogs.com/xiaoxuStudy/p/12564079.html