• es6新增系列—let和const命令


    一、let命令
    let命令用于声明变量,es6之前声明变量都是使用var命令,var命令存在很多弊端。
    let命令的特点
    1、不存在变量提升:
    var声明的变量,在变量声明之前使用不会报错,值为undefined,这样逻辑上讲不过去的,let命令声明的变量就抛弃了这种奇怪的变量提升的现象。

    // var
    console.log(a)  //  输出undefined
    var a = 1
    
     // let
     console.log(b) // 报错
     let b = 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2、不允许重复声明
    var的情况下,是可以重复声明同一个变量的,而在let声明的变量,如果重复声明会报错。

    // var
    var a = 1
    var a = 10
    console.log(a)  // 10
    
    
    // let 
    let b = 1
    let b = 10 //报错
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3、let命令会带来块级作用域
    在es6之前,js是不存在块级作用域的,只分为全局作用域和函数作用域,这就导致一个变量泄露到全局,内层变量覆盖外层变量的情况,在es6出现之前,开发人员都是用匿名函数解决这个问题。

    var i =100
    for(var i = 0; i < 10; i++) {
    var b = 5
    }
    //变量覆盖:这就是for循环里面的i变量覆盖了外面的i比那辆
    console.log(i) // 10  
    
    //变量泄露:在for循环中定义的变量,在外部作用域也可以读取
    console.log(b) // 5
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    有了es6之后,也就带来了块级作用域,解决了变量覆盖和变量泄露的问题,让变量只在当前作用域以及当前子孙作用域有效。

    {
    let i = 10
    console.log(i) // 10
    	{
    	console.log(i) // 10
    	}
    }
    console.log(i) // 报错:i is not defined
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    有一个经典的闭包问题

    for(var i = 0;i < 10; i++) {
    var a = "button"+i
    document.getElementById(a).onclick = alert(i)
    }
    // 我们想要的效果是,点击第一个button alert 1.....
    //在页面中点击任何一个button alert都是10
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在es6没出现之前是用闭包解决这个问题的

    for(var i = 0;i < 10; i++) {
    var a = "button"+i
    (function(i) {
    document.getElementById(a).onclick = alert(i)
    }(i))
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    有了局部作用域之后

    for(let i = 0;i < 10; i++) {
    let a = "button"+i
    document.getElementById(a).onclick = alert(i)
    }
    // 变量i是let声明的,当前的i只在本轮循环有效
    //所以每一次循环的i其实都是一个新的变量
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    值得一提: for(let i = 0;i < 10; i++) {let i = ‘ddd’} 的代码块,for设置循环变量的部分是父作用域。大括号是子作用域。

    4、暂时性死区
    ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错,暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。

    var tmp = 123;
    if (true) {
      tmp = 'abc'; // ReferenceError
      let tmp;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    总结:let命令和var命令的区别

    1、let不存在变量提升,var存在。
    2、let变量有局部作用域,不会出现内层变量覆盖外层变量,内层变量泄露的问题。
    3、let变量不能重复声明,会报错。
    4、let变量存在暂时性死区问题。

  • 相关阅读:
    Adobe 认证证书怎么考
    【ETH】【方案】如何获取以太坊内部交易?
    CRM系统中人工智能对销售业务的帮助
    Python的比较运算符查询表
    【mindspore】【训练警告】执行训练代码时存在的警告
    嵌入式Linux入门-异常与中断(流程+寄存器全解析)
    运动颈挂式蓝牙耳机推荐,推荐几款适合佩戴的骨传导耳机
    身份证号码算法解析与Java代码实现
    低代码在ERP中的理解与应用:提升开发效率与业务灵活性
    李沐动手学深度学习V2-GRU门控循环单元以及代码实现
  • 原文地址:https://blog.csdn.net/weixin_44312227/article/details/121862371