• es6 let介绍及应用场景


    关于更多es6建议去看阮一峰的博客~

    es6入门:http://es6.ruanyifeng.com/

    源码仓库:https://github.com/ruanyf/es6tutorial

    let介绍

    一.块级作用域(重点)。

       我们知道,在javascript中只有全局作用域和函数作用域,并不存在块级作用域。这样,在使用时就会出现一些问题。 下面我们先来举例说明let块级作用域的使用。

       例:

      代码如下所示: 

            {
                var a=5;
                let b=10;
            }
            console.log(a);
            console.log(b);

      我们在控制台得到的结果如下所示:

      也就是说,var声明的变量由于不存在块级作用域所以可以在全局环境中调用,而let声明的变量由于存在块级作用域所以不能在全局环境中调用。

    二.不存在变量提升

          var定义变量:可以先使用,后声明;而let定义变量:只可先声明,后使用。

    例:

      

    复制代码
            var num1=100;
            console.log(num1);
    
            let num2=200;
            console.log(num2);
    
            console.log(i);
            var i=10;
    
            console.log(j);
            let j=5;
    复制代码

        我们可以看到结果如下:

    即前两个都是先声明后使用,没有问题。而后两个都是先使用,后声明,用var 声明的显示undefined,而 let声明的直接报错。

    说明:console.log(i);

       var i=10;

    实际上相当于:

        var i;

        console.log(i);

       i=10;

    所以会出现undefined的情况。

    三.暂时性死区

      暂时性死区即:只要一进入当前作用域,所要使用的变量就已经存在,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。

    例5:

        var tmp=123;
        if(true){
            tmp="abc";
            let tmp;
        }

       结果如下:

    也就是说:虽然上面的代码中存在全局变量tmp,但是块级作用域内let又声明了一个局部变量tmp,导致后者绑定了块级作用域,所以在let声明变量前,对tmp赋值会报错。此即暂时性死区。

      

      注意:ES6规定暂时性死区和不存在变量提升就是为了减少运行时的错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。

      

      暂时性死区就是: 只要块级作用域内存在let,那么他所声明的变量就绑定了这个区域,不再受外部的影响。

      暂时性死区即 Temperary Dead Zone,即TDZ。 

      

           注意:暂时性死区也意味着 typeof 不再是一个百分之百安全的操作。  如下:

        if (true) {
          console.log(typeof x);
          let x;
        }

      这里如果没有let x,那么typeof x的结果是 undefined,但是如果使用了let x,因为let不存在变量提升,所以这里形成了暂时性死区,即typeof x也是会报错的。。。  从这里可以理解暂时性死区实际上就是这一部分是有问题的 。

    四.不允许重复声明

      

    复制代码
        function func (){
            let b=100;
            var b=10;
        }
    
        function add(num){
            let num;
            return num+1;
        }
    
        function another(){
            let a=10;
            let a=5;
        }
    复制代码

    上述三个得到的结果均为:

    只是前两者为 b和num被声明过了。注意:第二个函数,虽然我们没有明确的声明,但是参数实际上是相当于用var声明的局部变量。

    let应用

    • 因为闭包的存在,会给我们的应用中带来一些不必要的麻烦。比如下面的例子:
      <body>
          <input type="button" value="按钮1"    >
          <input type="button" value="按钮2"    >
          <input type="button" value="按钮3"    >
          <script type="text/javascript">
              var btns = document.getElementsByTagName("input");
              for (var i = 0; i < 3; i++) {
                  btns[i].onclick = function () {
                      alert("我是第" + (i + 1) + "个按钮");
                  };
              }
          </script>
      </body> 

      在实际点击button的时候,弹出的都是”我是第4个按钮”,这又是为什么呢?是因为闭包导致的,给onclick赋值的函数内部已经访问了另一个外部作用域的变量i,而闭包中使用的局部变量的值,一定是局部变量的最后的值。因此点击的时候,总是会读取i的最后一个值3,因此造成了每次点击都是“第4个按钮”。

    • 遇到这种问题,有三种解决方式供参考。

    • 方式1:给每个按钮添加一个属性,来保存每次i的临时值。
      <body>
          <input type="button" value="按钮1"    >
          <input type="button" value="按钮2"    >
          <input type="button" value="按钮3"    >
          <script type="text/javascript">
              var btns = document.getElementsByTagName("input");
              for (var i = 0; i < 3; i++) {
                  //把i的值绑定到按钮的一个属性上,那么以后i的值就和index的值没有关系了。
                  btns[i].index = i;
                  btns[i].onclick = function () {
                      alert("我是第" + (this.index + 1) + "个按钮");
                  };
              }
          </script>
      </body>
    • 方式2:使用匿名函数的自执行
      <body>
          <input type="button" value="按钮1"    >
          <input type="button" value="按钮2"    >
          <input type="button" value="按钮3"    >
          <script type="text/javascript">
              var btns = document.getElementsByTagName("input");
              for (var i = 0; i < 3; i++) {   
                  //因为匿名函数已经执行了,所以会把 i 的值传入到num中,注意是i的值,所以num
                  (function (num) {
                      btns[i].onclick = function () {
                          alert("我是第" + (num + 1) + "个按钮");
                      }
                  })(i);
              }
          </script>
      </body>

      方式3:使用es6新增的let声明变量i

      <body>
          <input type="button" value="按钮1"    >
          <input type="button" value="按钮2"    >
          <input type="button" value="按钮3"    >
          <script type="text/javascript">
              var btns = document.getElementsByTagName("input");
              for (let i = 0; i < 3; i++) {
                  btns[i].onclick = function () {
                      alert("我是第" + (i + 1) + "个按钮");
                  };
              }
          </script>
      </body> 
  • 相关阅读:
    HDU 1394Minimum Inversion Number 数状数组 逆序对数量和
    2016中国大学生程序设计竞赛(长春)-重现赛 1010Ugly Problem 回文数 模拟
    Codeforces 723C. Polycarp at the Radio 模拟
    hihoCode 1078 : 线段树的区间修改
    hihocode 1077 : RMQ问题再临-线段树
    POJ 2352Stars 树状数组
    Codeforces 714C. Sonya and Queries Tire树
    Codeforces 710C. Magic Odd Square n阶幻方
    Codeforces 709C 模拟
    ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined) D. The Door Problem 2-SAT
  • 原文地址:https://www.cnblogs.com/zhenguoli/p/8659053.html
Copyright © 2020-2023  润新知