在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>

样式和实现效果:

 

点击之后:

 

 

 

posted on 2020-08-08 16:47  Cloud%  阅读(647)  评论(0编辑  收藏  举报