• 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变量存在暂时性死区问题。

  • 相关阅读:
    分布式锁最实用解决方案--redisson分布式锁(一)
    HTTP 请求中的请求方法有哪些常见的类型?
    两天完成牛客网sql必知必会50题(附链接)
    Pytorch 的基本概念和使用场景介绍
    mybatis分页实现
    Mac电脑剪切键Command-X键失灵
    Kubernetes(k8s)的Pod控制器Deployment详细讲解
    Python基础入门例程6-NP6 牛牛的小数输出
    如何快速、简单地迁移Keil MDK工程项目到其他开发工具
    Kylin系统下离线安装依赖包
  • 原文地址:https://blog.csdn.net/weixin_44312227/article/details/121862371