let跟var的区别:

1、let声明的是块级作用域,而var声明的范围是函数作用域,
2、let声明的变量不会在作用域中被提升,而var会
3、与 var 关键字不同,使用 let 在全局作用域中声明的变量不会成为 window 对象的属性(var声明的变量则会)。

  1. if(true){
  2. let age = 26;
  3. console.log(age); // 26
  4. }
  5. console.log(age); //ReferenceError: age is not defined

let 也不允许同一个块作用域中出现冗余声明。这样会导致报错 :

  1. var name;
  2. var name;
  3. let age;
  4. let age; // SyntaxError: Identifier 'age' has already been declared

可以这样声明,因为不在同一个作用域

  1. function test() {
  2. let age = 30;
  3. if (true) {
  4. let age = 20;
  5. console.log(age); // 20
  6. }
  7. console.log(age); // 30
  8. }
  9. test();

for循环中的let声明

在let出现之前,for循环定义的迭代变量会渗透到循环体外部

  1. for (var i = 0; i < 5; i++){
  2. }
  3. console.log(i); // 5

改成使用let后,这个问题就消失了,因为迭代变量的作用域仅限于for循环块内部:

  1. for (let i = 0; i < 5; i++){
  2. }

在使用 var 的时候,最常见的问题就是对迭代变量的奇特声明和修改

  1. for (var i = 0; i < 5; i++){
  2. setTimeout(() => {
  3. console.log(i); // 5,5,5,5,5
  4. }, 0)
  5. }
  6. // 之所以会这样,是因为在退出循环时,迭代变量保存的是导致循环退出的值:5。在之后执行超时
  7. 逻辑时,所有的 i 都是同一个变量,因而输出的都是同一个最终值。

而在使用 let 声明迭代变量时,JavaScript 引擎在后台会为每个迭代循环声明一个新的迭代变量。
每个 setTimeout 引用的都是不同的变量实例,所以 console.log 输出的是我们期望的值,也就是循
环执行过程中每个迭代变量的值。

  1. for (let i = 0; i < 5; i++){
  2. setTimeout(() => {
  3. console.log(i); // 0,1,2,3,4
  4. }, 0)
  5. }
  6. tips:这种每次迭代声明一个独立变量实例的行为适用于所有风格的 for 循环,包括 for-in for-of
  7. 循环。