一、let 和 var 命令的区别

  1、范围:

  ES6 新增了 let 命令,用来声明变量,用法类似于 var,但是声明的变量,只有在 let 命令所在的代码块内有效;

  var 命令声明的变量,可以在全局来使用;

1
2
3
4
5
6
{
  var b = 1;
  let a = 10;
}
console.info(b);      // 打印 1
console.info(a);      // 报错 ReferenceError a is not defined

  let 非常适合使用在 for 循环中:

1
2
3
4
5
6
7
var a = [];
for (    let i = 0; i < 10; i++) {
  a[i] = function () {
    console.info(i);
  }
}
a[5]();     // 打印 5

  for 循环有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域:

1
2
3
4
5
// 打印了三次 abc
for (    let i = 0; i < 3; i++) {
  let i =     'abc' ;
  console.info(i);
}

  2、let 不存在变量提升, var 会发生变量提升:

  var 命令会发生变量提升的现象,即 变量可以在变量声明之前使用,值为 undefined。

  这种现象很奇怪,按照一般的逻辑,变量应该在声明语句之后才可以使用;

  解决方案:let 命令改变了语法的行为,它声明的变量一定要在 声明后 使用,否则报错:

1
2
3
4
5
6
7
// var 的情况
console.info(foo);      // 打印为 undefined
var foo = 2;
 
// let 的情况
console.info(bar);      // 报错 ReferenceError bar is not defined
let bar = 2;

  3、暂时性死区:

  只要块级作用域存在 let 命令,那么 let 声明的变量就 "绑定" 到这个区域,不再受到外部的影响:

  由于 存在全局变量 temp, 但是块级作用域内 let 又声明了一个局部变量 temp,导致后者绑定这个块级作用域,所以在 let 声明 temp 变量前,使用到 temp 会报错;

1
2
3
4
5
6
var temp =     "123" ;
if (    true ) {
  console.info(temp);      // 报错 ReferenceError
  let temp =     "321" ;
  console.info(temp);
}

  暂时性死区:在代码块内,使用 let 命令声明变量之前,该变量都是不可用的

  ES6 明确规定,如果区块内存在 let 和 const 命令,那么这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡事在声明之前使用了这些变量,就会报错;var 声明的变量会出现 undefined ,let 声明的变量会报 ReferenceError;

  {
    temp = "123";  // ReferenceError
    console.info(temp);

    let temp;
    console.info(temp);  // 打印 undefined

    temp = "321";
    console.info(temp);  // 打印 321
  }

  未声明变量时,typeof 的类型为 undefined,但是后面一旦有使用的情况(在变量声明前),那么会报错 ReferenceError:

  {
    console.info(typeof undeclared_variable);  // 打印 undefined
    console.info(typeof temp);  // 报错 ReferenceError
    let temp = "123";
    console.info(typeof temp); // 打印 string
    console.info(temp);  // 打印 123

    var x = x;  // 不报错
    let y = y;  // 报错 ReferenceError Cannot access 'y' before initializetion
  }

  4、不允许重复声明:

  let 不允许在相同的作用域内,重复声明同样的变量:

  {
    let a = 10;
    console.info(a);
    var a = 1;  // Identifier 'a' has already been declared
    console.info(a);
  }

  {
    let a = 10;
    console.info(a);
    let a = 1;  // Identifier 'a' has already been declared
    console.info(a);
  }

 

参考文档:https://es6.ruanyifeng.com/#docs/let

posted on   冷漠「」  阅读(92)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通



点击右上角即可分享
微信分享提示