js var, let, const特性

作者: EdmundChen | 来源:发表于2018-05-09 15:20 被阅读54次

    var, let, const 用来声明变量

    一、let

    用法

    声明变量和var类似,但是所声明的变量,只在let命令所在的代码块内有效。而var声明的变量在全局或者当前函数作用域有效。

    {
      let a = 1;
      var b = 2;
    }
    a // ReferenceError: a is not defined.
    b // 1
    
    存在变量提升

    var发生”变量提升“现象,即变量提升到当前作用域的最顶层,值为undefined。

    console.log(a); // 输出undefined
    var a = 1;
    console.log(b); // Uncaught ReferenceError: b is not defined
    let b = 2;
    
    暂时性死区

    只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。

    var tmp = 123;
    if (true) {
      typeof tmp; // ReferenceError
      tmp = 'abc'; // Uncaught ReferenceError: tmp is not defined
      let tmp;
    }
    

    暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。

    不允许重复声明

    // 报错
    function func() {
      let a = 10;
      var a = 1;
    }
    // 报错
    function func() {
      let a = 10;
      let a = 1;
    }
    

    块级作用域

    ES5 只有全局作用域和函数作用域,没有块级作用域

    无块级作用域的不合理之处
    • 第一种场景,内层变量可能会覆盖外层变量。
    var tmp = new Date();
    function f() {
      console.log(tmp);
      if (false) {
        var tmp = 'hello world';
      }
    }
    f(); // undefined
    
    • 第二种场景,内层变量可能会覆盖外层变量。
    var s = 'hello';
    for (var i = 0; i < s.length; i++) {
      console.log(s[i]);
    }
    console.log(i); // 5
    

    if代码块的外部使用外层的tmp变量,内部使用内层的tmp变量。但是,函数f执行后,输出结果为undefined,原因在于变量提升,导致内层的tmp变量覆盖了外层的tmp变量。

    ES6 的块级作用域
    function f1() {
      let n = 5;
      if (true) {
        let n = 10;
      }
      console.log(n); // 5
    }
    

    块级作用域的出现,实际上使得获得广泛应用的立即执行函数表达式(IIFE)不再必要了。

    // IIFE 写法
    (function () {
      var tmp = ...;
      ...
    }());
    
    // 块级作用域写法
    {
      let tmp = ...;
      ...
    }
    

    const

    基本用法

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

    const PI = 3.1415;
    PI // 3.1415
    PI = 3;
    // TypeError: Assignment to constant variable.
    

    本质

    const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。

    块级作用域与函数声明(略)

    相关文章

      网友评论

        本文标题:js var, let, const特性

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