美文网首页
ES6的块级作用域

ES6的块级作用域

作者: 前白 | 来源:发表于2020-11-23 17:49 被阅读0次

    本节我们来学习块级作用域,ES5 中只有全局作用域和函数作用域。这会导致函数作用域覆盖了全局作用域,或者循环中的变量泄露为全局变量。

    示例:

    函数作用域覆盖全局作用域:

    var a = 1;
    function test() {
        console.log(a);  // 由于变量提升,导致内层的a变量覆盖了外层的a变量
        if (true) {
            var a  = 10;
        }
    }
    test();   // 输出:undefined
    

    循环中的变量泄露为全局变量:

    for(var i=0; i<5; i++) {
        console.log(i);  // 输出:0 1 2 3 4
    }
    console.log(i); // 输出:5
    

    ES6的块级作用域

    let 实际上为 JavaScript 新增了块级作用域,外层作用域无法获取到内层作用域,这样非常安全。即使外层和内层都使用相同变量名,也都互不干扰。

    示例:

    例如下面这段代码:

    function test() {
        let a = 1;
        if(true){
          let a = 10;
          console.log(a);  // 输出:10
        }
        console.log(a);   // 输出:1
    }
    
    test();  // 调用函数
    

    在函数 test()if 语句代码块中都声明了变量 a,但是因为 let 命令声明的变量只在块级作用域中起作用,所以在 if 中输出 a 的值为 10,在 test() 中输出 a 的值为 1,这两者互不干扰。

    块级作用域与函数声明

    ES5 中规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。而在 ES6 中引入了块级作用域,允许函数可以在块级作用域中声明。块级作用域之中,函数声明语句的行为类似于 let,在块级作用域之外不可引用。

    示例:

    我们来看一个例子:

    {
        if(true){
            function test(){
                console.log("你好,侠课岛!")
            }
        }
    }
    
    test();
    

    执行代码,输出结果为“你好,侠课岛!”。

    但是一般考虑到兼容等问题,我们应该避免在块级作用域内声明函数。如果确实需要,也应该写成函数表达式,而不是函数声明语句。

    示例:

    上述代码使用函数表达式来写:

    {
        if(true){
            let test = function (){
                console.log("你好,侠课岛!");
            };
        }
    }
    

    除此之外,还有一个地方我们需要注意一下, ES6 的块级作用域必须有大括号,如果没有大括号,JavaScript 引擎就认为不存在块级作用域。

    示例:

    例如像下面这样写会报错:

    // 声明函数
    if (true)
        let func = function () {};
    
    // 声明变量
    if (true) let a = 1;
    

    报错信息如下所示:

    SyntaxError: Lexical declaration cannot appear in a single-statement context
    

    上述代码中因为没有大括号,所以不存在块级作用域,不管是声明函数还是声明变量都会报错。

    相关文章

      网友评论

          本文标题:ES6的块级作用域

          本文链接:https://www.haomeiwen.com/subject/cjuviktx.html