javascript中的块级作用域【详解】

1. 为什么需要块级作用域?

  • 第一种场景,内层变量可能会覆盖外层变量。

    var tmp = new Date();
    
    function f(){
        console.log(tmp);
        if(false){
            var tmp = 'hello world';
        }
    }
    
    f();//undefined
    
  • 第二种场景,用来计数的循环变量泄露为全局变量。

    var s = 'hello';
    
    for(var i = 0;i<s.length;i++){
        console.log(s[i]);
    }
    
    console.log(i);//5
    

2. ES6的块级作用域

  • let实际上为JavaScript新增了块级作用域。

  • ES6允许块级作用域的任意嵌套。

  • 内层作用域可以定义外层作用域的同名变量。

  • 块级作用域的出现,实际上使得广泛应用的匿名立即执行函数表达式(IIFE)不再必要了。

3. 块级作用域与函数声明

  • ES5规定,函数只能在顶层作用域函数作用域之中声明,不能在块级作用域声明。

    //情况一
    if(true){
        function f(){}
    }
    
    //情况二
    try{
        function f(){}
    }catch(e){
        //...
    }
    
    //上面两种函数声明,根据ES5的规定都是非法的。
    //但是,浏览器没有遵守这个规定,为了兼容以前的旧代码,还是支持在块级作用域之中声明函数,因此上面两种情况实际都能运行,不会报错。
    

    ES6引入块级作用域,明确允许在块级作用域之中声明函数。ES6规定,块级作用域之中,函数声明语句类似于let,在块级作用域之外不可引用。

    function f(){ console.log('I am outside!'); }
    
    (function (){
        if(false){
            function f(){ console.log('I am inside!'); }
        }
        f();
    })
    //ES5环境
    //'I am inside!'
    
    //ES6环境
    // Uncaught TypeError: f is not a function
    

    ES6有块级作用域,为什么还会这样呢?

    原来,如果改变了块级作用域内声明的函数的处理规则,显然会对老代码产生很大影响。为了减轻因此产生的不兼容问题,ES6 在附录 B里面规定,浏览器的实现可以不遵守上面的规定,有自己的行为方式

    但是三条规则只针对ES6环境

    • 允许在块级作用域内声明函数。

    • 函数声明类似于var,即会提升到全局作用域或函数作用域的头部。

    • 同时,函数声明还会提升到所在的块级作用域的头部。

    考虑到环境导致的行为差异太大,应该避免在块级作用域内声明函数。如果确实需要,也应该写成函数表达式,而不是函数声明语句

    // 块级作用域内部的函数声明语句,建议不要使用
    {
      let a = 'secret';
      function f() {
        return a;
      }
    }
    
    // 块级作用域内部,优先使用函数表达式
    {
      let a = 'secret';
      let f = function () {
        return a;
      };
    }
    

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

  • 24
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小井

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值