zoukankan      html  css  js  c++  java
  • ES6 块级作用域解决的一些问题

    ES6 块级作用域解决的一些问题

    博客说明

    文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢!

    简介

    ES5中没有块级作用域,这出现了许多的问题,ES6中新增了块级作用域

    问题一:内层变量覆盖外层变量

    由于使用var声明的变量,存在变量提升,在内层的tmp会覆盖掉外层的tmp变量

    var tmp = 'hahaha';
    
    function f() {
      console.log(tmp);
      if (false) {
        var tmp = 'hello world';
      }
    }
    
    f(); // undefined
    

    问题二:在for循环中的循环变量泄漏为全局变量

    在使用for循环时,i变量在循环结束之后并没有回收,而是泄漏成了全局变量

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

    ES6的块级别作用域

    letconst为JavaScript新增了块级作用域

    在同一个块级里面,外层代码块不受内层代码块的影响

    function f1() {
      let n = 5;
      if (true) {
        let n = 10;
      }
      console.log(n); // 5
    }
    

    函数声明

    ES5 规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。但是,浏览器没有遵守这个规定,为了兼容以前的旧代码,还是支持在块级作用域之中声明函数,因此上面两种情况实际都能运行,不会报错。

    像以下的代码,在ES5中是非法的,但是在浏览器中不会报错的

    // 情况一
    if (true) {
      function f() {}
    }
    
    // 情况二
    try {
      function f() {}
    } catch(e) {
      // ...
    }
    

    虽然不报错,但是ES6还是解决了这个问题,ES6 引入了块级作用域,明确允许在块级作用域之中声明函数。

    ES6 规定,块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用。

    但是这样改动对老代码十分不友好,为了减轻因此产生的不兼容问题,ES6 在附录 B里面规定,浏览器的实现可以不遵守上面的规定,有自己的行为方式。

    • 允许在块级作用域内声明函数。
    • 函数声明类似于var,即会提升到全局作用域或函数作用域的头部。
    • 同时,函数声明还会提升到所在的块级作用域的头部。

    注意,上面三条规则只对 ES6 的浏览器实现有效,其他环境的实现不用遵守,还是将块级作用域的函数声明当作let处理。

    函数表达式和函数声明

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

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

    作用域的标识

    ES6 的块级作用域必须有大括号,也就是标识,如果没有大括号,JavaScript 引擎就认为不存在块级作用域。

    if (true) let x = 1;  // 报错
    
    
    if (true) {
      let x = 1;
    }
    // 不报错
    

    感谢

    万能的网络

    菜鸟教程

    阮一峰的es6语法教程

    以及勤劳的自己,个人博客GitHub

    微信公众号

  • 相关阅读:
    Comprehend-Elasticsearch-Demo5
    Mxnet使用TensorRT加速模型--Mxnet官方例子
    Mxnet模型转换ONNX,再用tensorrt执行前向运算
    MxNet模型转换Onnx
    基于Flask-APScheduler实现添加动态定时任务
    Golang习题
    算法题
    Celery使用指南
    flask拓展(数据库操作)
    flask进阶(上下文源管理源码浅析)
  • 原文地址:https://www.cnblogs.com/guizimo/p/14957449.html
Copyright © 2011-2022 走看看