ES6笔记 - let和const命令

let和const命令

1. let命令

  • let命令的用法和var类似,其核心特点为只在let所在的代码块内有效。由此衍生出几个特点:
    1. 不存在变量提升

      • 变量提升是指,变量可以在声明之前使用,此时值为undefined
      • let所声明的变量一定要在声明后使用,否则会报错
    2. 不允许重复声明

      //var的情况
      console.log(foo);	//输出undefined
      var foo = 2;
      var foo = 3;
      console.log(foo);	//输出3
      
      //let的情况
      console.log(bar);	//报错
      let bar = 2;
      let bar = 3;		//报错
      

2. const命令

  • const声明一个只读的常量,一旦声明,常量的值就不能变

    const的特性与let极为相似,包括只在命令所在的代码块内有效、不会提升、不允许重复说明

  • const常量一旦声明就必须立刻初始化,否则就会报错

    const foo; //报错
    const foo = 5; //正确
    
  • 将一个数组或对象声明为常量需要小心。和java中的指针一样,const所保证的实际上并不是变量的值不得改动,而是变量指向的内存地址所保存的数据不得改动。正如java中const只能保证指针指向方向,而不能保证所指方向的数据内部能否改变一样。

3. 块级作用域

  • ES5中只有全局作用域和函数作用域,这样就很容易造成变量之间的覆盖或泄露

    let为JS新增了块级作用域,它和Java中的局部作用域有相似之处:

    • 外层代码块不受内层代码块影响
    • 外层作用域无法读取内层作用域的变量
    • 内层作用域可以定义外层作用域的同名变量
    function f1() {
      let n = 5;
      if (true) {
        let n = 10;
      }
      console.log(n); // 5
    }
    
  • 注意

    • 由于各种原因,应该避免在块级作用域内声明函数。如果确实需要,也应该写成函数表达式,而不是函数声明语句

    • ES6的块级作用域必须有大括号,如果没有大括号,JS引擎就不认为存在块级作用域

      // 第一种写法,报错
      if (true) let x = 1;
      
      // 第二种写法,不报错
      if (true) {
        let x = 1;
      }
      

      在上面的代码中,由于let只能出现在当前作用域的”顶层“,而第一种写法将他作为全局作用域中if的子语句,并非”顶层“,所以报错

4. 从function循环问题深入了解let

var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); //输出10
  • 这段代码中,由于i是全局变量,存在变量提升,所以值会一直更迭到10

    由于function中储存的是变量i,而不是具体数值,所以一旦调用,就会寻找到变量i的地址,最后得出结果10

var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); //输出6
  • 这段代码中,由于变量i是let声明的,所以当前的i只在本轮循环有效,即每一次循环的i其实都是一个新的独立的变量(这一点和Java中的很不一样)

    当function调用时,会寻找当时存储的那个独立的i的地址,所以最后输出的是6。

  • 更多可以得知的信息

    1. i在离开作用域后并不会被立即销毁,这点和java中的局部变量不一样
    2. JS引擎内部会记住上一轮循环的值,初始化本轮的i时,就会在上一轮的基础上计算。这样for循环就能正常迭代i的值
    3. for由两个作用域组成:一个父作用域(设置循环变量部分)和一个子作用域(循环体内部),两个作用域是不相冲突的,都可以设置同名let变量
posted @   Solitary-Rhyme  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示