一、let 和 const ------ 2019-08-18

1、let和var的区别:

/**
* 1、Let不存在变量提升,当前作用域中,不能在Let声明前使用变量;
* 2、同一个作用域中,Let不允许重复声明;
* 3、Let解决了typeof的一个暂时性死区问题;
* 4、在全局作用域中,使用Let声明的变量并没有给window加上对应
*   的属性
* 5、Let会存在块级作用域,除对象以外的大括号都可以被看作私有
*  块级作用域;
*/

1、块级作用域:简单说一个 {} 就构建 了一个块级作用域;

2、let使用的注意事项:

(1) let在块级作用域中没有预解析,不存在变量提升;这是和var不同的一点;

if (true) {
  console.log(tmp) //  Cannot access 'tmp' before initialization
  let tmp = '123';
}
由于使用let定义的变量不存在与解析,所以,在作用域中定义这个变量之前使用会报错;
错误信息是:Cannot access 'tmp' before initialization;

(2)暂时性死区(temporal dead zone,简称 TDZ):只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。

var tmp = 123;
if (true) {
  tmp = 'abc'; // ReferenceError
  let tmp;
}
只要我们在作用域中使用了let定义了这个变量,那么就必须先定义后使用,
就算我们在全局作用域或者父作用域中也定义了这个变量也不行,这就是暂时性死区;

(3)在同一个作用域中不允许使用let重复定义变量:

 if (true) {
        let tmp = 1;
        let tmp = 2;
        console.log(tmp); 
        //Uncaught SyntaxError: Identifier 'tmp' has already been declared
  }
在ES6中,使用let重复定义变量是会报错的;
 if (true) {
        var tmp = 1;
        var tmp = 2;
        console.log(tmp); // 2
    }
但是在ES5中则不会,后面定义的 变量会覆盖前面的;

(4)for循环存在的特殊情况:

for (let i = 0; i < 3; i++) {
        console.log(i) // 输出0,1,2
}

for (let i = 0; i < 3; i++) {
       let i = 'test';
        console.log(i) // 输出三次test
}
这就说明:
for循环的小括号 ()中是一个作用域,相当于父级作用域,因为能在 {} 中访问;
for循环的 {} 中相当于子级作用域;

(5)let的一个典型优势

 let arr = []
 for (let i = 0; i < 10; i++) {
        arr[i] = function () {
            console.log(i)
        }
 }
arr[5](); // 输出 5

//  使用var
var  arr = []
for (var  i = 0; i < 10; i++) {
    arr[i] = function () {
         console.log(i)
    }
 }
arr[5](); // 输出 10

3、const使用的注意事项:

(1)上面let的注意事项,const也适用;

(2)const定义的变量不能被修改,否则会报错;

const a = 1;
a = 2;
console.log(a); // Assignment to constant variable.

(3)const定义完变量,必须有值,不能后赋值,不能修改;

const a ;
a = 2;
console.log(a); // Missing initializer in const declaration

你可能感兴趣的:(一、let 和 const ------ 2019-08-18)