let const

作者: YJ_1101 | 来源:发表于2018-09-12 16:55 被阅读0次

    let

    块级作用域

    内层变量不可能覆盖外层变量
    用来计数的循环变量不会泄露为全局变量
    块级作用域的出现,立即执行函数表达式(IIFE)就不再必要了。

    var a = [];
    for (let i = 0; i < 10; i++) {
      a[i] = function () {
        console.log(i);
      };
    }
    a[6](); // 6
    
    // 用babel转为es5后
    
    "use strict";
    
    var a = [];
    
    var _loop = function _loop(i) {
      a[i] = function () {
        console.log(i);
      };
    };
    
    for (var i = 0; i < 10; i++) {
      _loop(i);
    }
    a[6](); // 6
    

    JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。 (只在for循环有用)

    let i=0;i++;
    console.log(i); // 1
     i=0;i++;
    console.log(i); // 1
    
    立即执行函数表达式(IIFE)
    // 最常用的两种写法
    (function(){ /* code */ }()); // 老道推荐写法
    (function(){ /* code */ })(); // 当然这种也可以
    
    // 括号和JS的一些操作符(如 = && || ,等)可以在函数表达式和函数声明上消除歧义
    // 如下代码中,解析器已经知道一个是表达式了,于是也会把另一个默认为表达式
    // 但是两者交换则会报错
    var i = function(){ return 10; }();
    true && function(){ /* code */ }();
    0, function(){ /* code */ }();
    
    // 也可以选择一元运算符
    !function(){ /* code */ }();
    ~function(){ /* code */ }();
    -function(){ /* code */ }();
    +function(){ /* code */ }();
    
    // 也可以这样
    new function(){ /* code */ }
    new function(){ /* code */ }() // 带参数
    
    块级作用域与函数声明:

    ES5 规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。 ES6
    引入了块级作用域,明确允许在块级作用域之中声明函数。ES6 规定,块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用。
    为了减轻因此产生的不兼容问题,ES6在附录B里面规定,浏览器的实现可以不遵守上面的规定,有自己的行为方式。
    1、允许在块级作用域内声明函数
    2、函数声明类似于var 会提升到全局作用域的头部
    3、函数声明还会提升到块级作用域的头部

    不存在变量提升

    let不会像var那样会发生‘变量提升’现象即函数及变量的声明都将被提升到函数的最顶部。。所以变量一定要在声明后使用,否则报错。

    不允许重复声明

    let不允许在相同作用域内重复声明同一个变量

    暂时性死区(TDZ)

    如果区块存在let和const命令,则这个区块对这些命令声明的变量从一开始就形成封闭作用域。只要在声明前使用这些变量,就会报错。
    在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。

    if (true) {
      // TDZ开始
      tmp = 'abc'; // ReferenceError
      console.log(tmp); // ReferenceError
    
      let tmp; // TDZ结束
      console.log(tmp); // undefined
    
      tmp = 123;
      console.log(tmp); // 123
    }
    
    function a() {
      console.log(i);
      function b(){
        let i = 10;
        console.log(j);
        function c(){
            let j = 20;
          console.log(i);
          console.log(j)
        }
        c()
      }
      b()
    }
    a()  // Uncaught ReferenceError: i is not defined
    
    //转为es5
    "use strict";
    
    function a() {
      console.log(i);
      function b() {
        var i = 10;
        console.log(j);
        function c() {
          var j = 20;
          console.log(i);
          console.log(j);
        }
        c();
      }
      b();
    }
    a();
    
    function a () {
      console.log(i);
      let i = 10;
      console.log(j);
      let j = 20;
      console.log(i);
      console.log(j);
    }
    //转为es5
    "use strict";
    
    function a() {
      console.log(i);
      var i = 10;
      console.log(j);
      var j = 20;
      console.log(i);
      console.log(j);
    }
    

    const

    const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。

    const声明一个只读的常量,一旦声明,常量的值就不能改变,这意味着,const一旦声明常量,就必须立即初始化,不能等到之后再赋值。因此,改变常量和只声明不赋初始值都会报错。

    var i = 5;
    let j = 10;
    const i =6; // 报错
    const j = 11; // 报错
    
    // JS是按照代码块来进行编译和执行的,每一个script就是一个块,代码块间相互独立,但变量和方法共享
    <script>
      const foo = 1  
    </script>
    <script>
      foo = 2
    </script>
    // Uncaught TypeError: Assignment to constant variable.
    

    对于复合类型的常量,常量名不指向数据,而是指向数据所在的地址。const命令只是保证常量名指向的地址不变,并不保证该地址的数据不变,也就是说,将对象常量指向另一个地址会报错,但对象本身是可变的,可以为其添加,修改属性,因此将一个对象声明为常量必须十分小心。

    const obj = {};
    obj.name = “Alice”;
    obj = {}; // 报错
    
    跨模块常量

    const声明的常量只能在当前代码块有效,如果想设置跨模块的常量可以采用下面的写法:

    //constants.js 
    export const A = 1;
    export const B = 1;
    export const C = 1;
    
    //test1.js
    import * as constants from './constants'
    
    //test2.js
    import {A, B} from './constants'
    

    相关文章

      网友评论

          本文标题:let const

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