zoukankan      html  css  js  c++  java
  • ES6:let声明以及声明特性

    在ES6中新增加了 let,let 和 var 的用法类似,都是用以声明变量。

    let声明变量的方式也和var类似,声明变量或是声明变量并附初始值。

    let a;
    let b,c,d;
    let e = 100;
    let f = 251;g = 'qq',h = [];

    let的特性:

    变量不可重复声明、有块级作用域、不存在变量提升、暂时性死区、不影响作用域链

    1、变量不可重复声明

    在同一个作用域中,与var 不同的是,不可以使用let重复声明同一个变量

    function qq(){
                var a = 11;
                let a = 22;
            } 
    //  SyntaxError:Identifier 'a' has already been declared(标识符a已经被声明)
     function qq(){
                let a = 11;
                let a = 22;
            }
    //SyntaxError: Identifier 'a' has already been declared(标识符‘a‘已经被重复声明)

    使用var 声明变量的时候就不会出现重复声明报错的问题可以重复声明,但是使用let 可以防止变量命名的重复,防止变量污染。

    2、块级作用域

    作用域包括:全局作用域、函数作用域、eval

    let声明的变量有块级作用域,其声明的变量,只在let 命令所在的代码块内有效。

    块级作用域:在代码块内有效,在代码块外无效。if、else、for等后面的 { } 

    {
        var a = 11;
        let b = 22;  
    }
    
    console.log(a); //11
    console.log(b); //ReferenceError: a is not defined.

    在代码块的范围内分别用 let和var声明了两个变量,因为var没有块级作用域,所以在代码块外面调用a,可以正常的返回a的值。

    在代码块外面调用b,因为let有块级作用域所以会报错。

    3、不存在变量提升

    在声明var的时候会存在变量提升,但是let 不存在像 var那样会发生变量提升。所以使用 let 声明变量的时候,一定要在声明之后使用。

    console.log(aa);  //返回undefined
    console.log(bb);  //报错 ReferenceError
    
    var aa = 11;
    var bb = 22;

     使用 var 声明的 aa,则会发生变量声明,代码运行的时候就相当于在最前面声明了变量但是并没有赋值,所以最终会输出undefined。而用 let声明的 bb,则不会发生变量提升,在声明变量之前,该变量都是不存在的,如果在前面调用bb,就会返回error。

    4、不影响作用域链

    {
       let  aa = 'ww';
       function fn() {
           console.log(aa);
        }
       fn();
    }    
    //结果输出 'ww'

    在函数作用域中没有查找到 aa,则就会向上级查找aa,发现已经声明赋值的aa,所以最后返回结果 ww

    5、暂时性死区

    只要块级作用域内部存在 let 命令,它所声明的变量就会绑定(binding)这个区域,不受外界的影响。

    var aa = 111;
    
    if (true) {
      aa = 'ww'; // ReferenceError
      let aa;
    }

    上面代码中,有着全局变量 aa,但是在块级作用域内部 let 又声明了一个局部变量 aa。let声明的这个变量只在块级作用域内有效,绑定了这个块级作用域,所以在 let 声明变量之前对 aa 赋值则会报错。

    在ES6中明确规定,如果区块中存在着let 和 const 命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。所以在代码块中,使用let 命令声明变量之前,该变量都是不可用的。这在语法上称为 “暂时性死区” (temporal dead zone,简称 TDZ)

    ES6 规定怎实行死区和 let、const 不出现变量提升,只要是为了减少运行时的错误,防止在变量声明之前就使用这个变量,从而导致意外行为,有了这种规定之后,就可以很容易地规避这种错误。

    总结来说,暂时性死区的本质就是,只要已进入当前作用域,所需要使用的变量已经存在了,但是无法获取(即不会发生变量提升提升)只有等到声明变量代码出现的时候,才可以正常地使用这个变量。

    let实例:

    在这个例子中想实现的效果是点击方块后改变其背景颜色为粉色。

    注意  for循环计数器

    因为let 存在块级作用域等特点,所以for 循环计数器,非常适合使用 let开声明变量。

    for(let i = 0;i<=3;i++){
        console.log(i);  // 1、2、3
    };
    
    console.log(i);  //ReferenceError: i is not defined

    使用let 声明的变量 i ,只在 for 循环体内部有效,在for循环体外调用就会报错。

    使用var 在for循环中,最后输出的还是4 。因为变量 i 是由var 声明的,因为var没有块级作用域,所以i 是直接存在全局中的,每一次循环,新的 i 值都会覆盖旧的值,所以最后输出的 i 值是经过更新表达式更新之后的值4。

    var a = [];
    for(let i = 0;i<=3;i++) {
        a[i] = function() {
            console.log(i);
        };
    }
    a[2]();  //4
    console.log(i);  //4

    但是如果使用的是 let声明,由于块级作用域的存在,当前的i 也只是在本循环内有效,每次循环的 i 都是一个新的变量,所以最后输出的是2。(如下所示)

    var a = [];
    for(let i = 0;i<=3;i++) {
        a[i] = function() {
            console.log(i);
        };
    }
    a[2]();  //2

    了解了 let 的特性之后,所以在本例中使用 let更为合理,使用 var 则会报错。

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     6     <title>let案例</title>
     7     <style>
     8         .container{
     9             width: 500px;
    10             height:400px;
    11             margin:100px auto;
    12             color:#999;
    13         }
    14         .page-header{
    15             font-size:30px;
    16             padding:10px;
    17             border-bottom:1px solid #999;
    18             margin-bottom:20px;
    19         }
    20         .item{
    21             margin-right:10px;
    22             float:left;
    23             width:100px;
    24             height:50px;
    25             border:2px solid teal;
    26         }
    27     </style>
    28 </head>
    29 <body>
    30     <div class='container'>
    31         <h2 class='page-header'>点击切换颜色</h2>
    32         <div class="item"></div>
    33         <div class="item"></div>
    34         <div class="item"></div>
    35     </div>
    36     <script>
    37         // 获取div元素对象
    38         let items = document.getElementsByClassName('item');
    39         // 遍历并且绑定事件
    40          for(let i = 0 ; i < items.length ; i++){
    41              //  如果使用的是var,var没有块级作用域,在for循环中的var实际上还是在全局作用域中。
    42              items[i].onclick = function() {
    43                 //  修改当前元素的背景颜色
    44                 items[i].style.background = 'pink';
    45              } 
    46          }
    47          console.log(i);
    48     </script>
    49 </body>
    50 </html>

    样式和实现效果:

    点击之后:

     

  • 相关阅读:
    Don't set high speed for the 'DoubleClick'
    How to set UITextField to ReadOnly
    Parallel World 1 并行世界的两个基本问题
    Parallel World 3 – Parallel Loop (2)
    hdu 2680 Choose the best route Dijkstra 虚拟点
    hdu 2255 KM算法
    最小生成树 kruskal 和 pime 模版
    hdu 1863 畅通工程 最小生成树+并查集
    hdu 2603 过山车 最大匹配,匈牙利算法模板(易理解)
    KM 最优匹配 讲解
  • 原文地址:https://www.cnblogs.com/nyw1983/p/13436551.html
Copyright © 2011-2022 走看看