美文网首页
杂货小铺之ES6+ 🍕 Let

杂货小铺之ES6+ 🍕 Let

作者: 羊驼驼驼驼 | 来源:发表于2020-07-03 22:31 被阅读0次
    es.png
    • let

    📖 ES6新增了let命令,用来声明变量

    1. let声明的全局变量不是全局对象window的属性;
      var a = 5;
      console.log(window.a); // 5
    
      🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻
    
      let a = 5;
      console.log(window.a); // undefined
    

    🔎 \color{Orange}{Warning}:
    var声明的全局变量是window的属性,是可以通过window.变量名的方式访问这些变量,而let声明的变量不能通过这种方式访问

    1. 用let定义变量不允许重复声明;
    var a = 5;
    var a = 6;
    console.log(a); // 6
    
    🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻
    
    let a = 5;
    let a = 6;
    console.log(a); // 报错:Uncaught SyntaxError: Identifier 'a' has already been declared
    
    1. let声明的变量不存在变量提升;
    function foo() {
      console.log(a)
      var a = 5;
    }
    foo() // undefined
    
    // 等同于
    
    function foo() {
      var a;
      console.log(a)
      a = 5
    }
    foo() // undefined
    

    🔎 \color{Orange}{Warning}:
    a的调用在声明之前,它的值是undefined,而不是Uncaught ReferenceError。实际上因为var会导致变量提升

    function foo() {
      console.log(a)
      let a = 5;
    }
    foo() // 报错:Uncaught ReferenceError: Cannot access 'a' before initialization
    

    🔎 \color{Orange}{Warning}:
    a的调用在声明之前,因为let没有发生变量提升,所以读取a的时候,并没有找到,而是在调用之后才找到let对a的定义,所以会报错

    4.let声明的变量具有暂时性死区;

    var a = 5;
    if(true) {
      a = 6;
      let a;
    }
    // 报错:Uncaught ReferenceError: Cannot access 'a' before initialization
    

    🔎 \color{Orange}{Warning}:
    上面代码中,存在全局变量a,但是块级作用域内let又声明了一个局部变量a,导致后者绑定这个块级作用域,所以在let声明变量前,对a赋值会报错;
    如果区块中存在letconst命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域,凡是在声明之前使用这些变化,就会报错

    function foo(a = b, b = 3) {
      console.log(a,b);
    }
    foo() // 报错:Uncaught ReferenceError: Cannot access 'a' before initialization
    // 等号是把等号右边的值赋值给等号左边 代码从左向右执行,b还没有值所以会报错
    
    🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻
    
    function foo(a = 2, b = a) {
      console.log(a,b);
    }
    foo() // 2 2
    
    1. let 声明的变量拥有块级作用域;
    for(var i = 0; i < 3; i++) {
      console.log('循环内:' + i);  // 0 1 2 
    }
    console.log('循环外:' + i); // 3
    
    🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻
    
    for(let i = 0; i < 3; i++) {
      console.log('循环内:' + i);  // 0 1 2 
    }
    console.log('循环外:' + i); // ReferenceError: i is not defined
    
    
    if(false) {
      var a = 5;
    }
    console.log(a); // undefined
    
    🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻
    
    if(false) {
      let a = 5;
    }
    console.log(a);  // 报错 Uncaught ReferenceError: a is not defined
    

    🔎 \color{Orange}{Warning}:
    使用let定义的变量,它的作用域是这个代码块内部,外部无法访问

    1. 思考🧐 怎么输出0、1、2;
    for(var i = 0; i < 3; i++) {
      setTimeout(function(){
        console.log(i); // 3 3 3
      })
    }
    
    //  解决方案1:闭包
    for(let i = 0; i < 3; i++) {
      (function(j) {
        setTimeout(function() {
          console.log(j); // 0 1 2
        })
       })(i)
    }
    
    🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻
    
    //  解决方案2:let
    for(let i = 0; i < 3; i++) {
      setTimeout(function(){
        console.log(i); // 0 1 2
      })
    }
    

    🔎 \color{Orange}{Warning}:
    把第二个解决方案粘贴到babel中:https://www.babeljs.cn/rep 转换成es5的代码,会是什么样呢?

    // babel 其实把这段代码转化成了闭包的形式
    "use strict"
    
    var _loop = function _loop(i) {
        setTimeout(function() {
            console.log(i);
        })
    }
    
    for (var i = 0 i < 3 i++) {
        _loop(i);
    }
    

    相关文章

      网友评论

          本文标题:杂货小铺之ES6+ 🍕 Let

          本文链接:https://www.haomeiwen.com/subject/uvneqktx.html