zoukankan      html  css  js  c++  java
  • 【02】块级作用域

    【02】块级作用域
     
    魔芋总结:
    为什么要有块级作用域?
    • 01,内层变量覆盖外层变量,因为变量提升。函数提升。
    • 02,用来计数的循环变量泄露为全局变量。循环结束后,它并没有消失,泄露成了全局变量。
     
    03,ES6允许块级作用域的任意嵌套。
    04,内层作用域可以和外层作用域定义同名的变量。
    05,立即执行匿名函数(IIFE)不再必要了。
    06,函数的作用域,在其定义的块级作用域之内。
     
    需要注意的是,如果在严格模式下,函数只能在顶层作用域和函数内声明,其他情况(比如if代码块、循环代码块)的声明都会报错。
     
     
     

     
    块级作用域
    为什么需要块级作用域?
    ES5只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。
     
    第一种场景,内层变量可能会覆盖外层变量。
    var tmp = new Date();
    
    function f(){
      console.log(tmp);
      if (false){
        var tmp = "hello world";
      }
    }
    
    f() // undefined
    
     
    上面代码中,函数f执行后,输出结果为undefined,原因在于变量提升,导致内层的tmp变量覆盖了外层的tmp变量。
     
     
    第二种场景,用来计数的循环变量泄露为全局变量。
    var s = 'hello';
    
    for (var i = 0; i < s.length; i++){
      console.log(s[i]);
    }
    
    console.log(i); // 5
    
     
    上面代码中,变量i只用来控制循环,但是循环结束后,它并没有消失,泄露成了全局变量。
     
    ES6的块级作用域
    let实际上为JavaScript新增了块级作用域。
    function f1() {
      let n = 5;
      if (true) {
        let n = 10;
      }
      console.log(n); // 5
    }
    
     
    上面的函数有两个代码块,都声明了变量n,运行后输出5。这表示外层代码块不受内层代码块的影响。如果使用var定义变量n,最后输出的值就是10。
     
    ES6允许块级作用域的任意嵌套。
    {{{{{let insane = 'Hello World'}}}}};
    
     
    上面代码使用了一个五层的块级作用域。外层作用域无法读取内层作用域的变量。
    {{{{{let insane = 'Hello World'}
      console.log(insane); // 报错
    }}}};
    
     
    内层作用域可以定义外层作用域的同名变量。
    {{{{let insane = 'Hello World';{let insane = 'Hello World';}}}}};
    
     

     
     
     
    块级作用域的出现,实际上使得获得广泛应用的立即执行匿名函数(IIFE)不再必要了。
    // IIFE写法
    (function () {var tmp = ...;...}());
    // 块级作用域写法
    {let tmp = ...;...}
    
     
     
     

    另外,ES6也规定,函数本身的作用域,在其所在的块级作用域之内。
    function f() {
    	console.log('I am outside!');
    }
    (function () {
    	if (false) { // 重复声明一次函数f
    		function f() {
    			console.log('I am inside!');
    		}
    	}
    	f();
    }());
    
     
     
    上面代码在ES5中运行,会得到“I am inside!”,但是在ES6中运行,会得到“I am outside!”。这是因为ES5存在函数提升,不管会不会进入 if代码块,函数声明都会提升到当前作用域的顶部,得到执行;而ES6支持块级作用域,不管会不会进入if代码块,其内部声明的函数皆不会影响到作用域的外部。
     
    {
      let a = 'secret';
      function f() {
        return a;
      }
    }
    f() // 报错
    
     
    上面代码中,块级作用域外部,无法调用块级作用域内部定义的函数。如果确实需要调用,就要像下面这样处理。
    let f;{let a = 'secret';
      f = function () {return a;}}f(); // "secret"
    
     

    原文作者:阮一峰
     
     

    **

  • 相关阅读:
    Java-使用IO流对大文件进行分割和分割后的合并
    Java-单向链表算法
    Java-二分查找算法
    Java-二叉树算法
    Java-对象比较器
    Android中Activity的四种开发模式
    Struts2工作原理
    C++实现单例模式
    数组中有一个数字出现的次数超过数组的一半,请找出这个数字
    c++ enum用法【转】
  • 原文地址:https://www.cnblogs.com/moyuling/p/8992514.html
Copyright © 2011-2022 走看看