zoukankan      html  css  js  c++  java
  • JavaScript 新旧替换一:变量声明

    目录

    引子

    在工作中,最初接触 ES5 的语法比较多,后来渐渐的接触了新的语法。由于一些原因,需要在不同的项目使用不同的语法。时间长了,发现在写代码的时候,偏向用更加熟悉的旧语法,但感觉这么下去不太妙。于是,就想着针对工作中常用的旧语法,跟可以替换的新语法进行对比,加深印象,然后记录总结一下,有意识的更新相关知识点。

    ES5 方式

    在 JavaScript 中,变量可以用来保存任何类型的数据。每个变量只是一个用于保存值的占位符而已。在 ES5 中,使用 var 声明变量,这种声明方式的特点有:

    1. 声明的变量不赋值,会初始化默认值为 undefined
    var testVariable;
    console.info('testVariable=',testVariable); // undefined
    
    1. 可以一条语句定义多个变量,变量之间用逗号分开。
    var name = 'Tom',
        age = 15;
    
    1. 如果省略 var 声明,则会创建一个全局变量,这样会污染全局变量,这种方式不推荐。
    2. var 声明的变量会自动添加到最近的环境中,当查找变量的时候,搜索过程是从作用域链的前端开始,向上逐级查询。如果在局部环境中找到了变量,则停止搜索,使用找到的变量。
    3. 同一作用域内重复声明同一变量时,后声明会覆盖前声明。
    var testVariable = '123';
    var testVariable = '12';
    console.info('testVariable=',testVariable); //12
    
    1. 声明的变量会发生“变量提升”,也就是说可以先使用后声明,这种方式不推荐。
    console.info('testVariable=',testVariable); // undefined
    var testVariable = 1;
    

    使用 var 声明比较经典的现象是在 for 循环语句中。

    function printNum() {
      var numArray = [];
      for(var i=0;i<5;i++) {
        numArray.push(function (){
          console.info(i);
        })
      }
      numArray[0]();
    }
    printNum(); // 5
    

    for 循环中用 var 声明的变量 i 在函数 printNum 作用域中都有效,每次循环执行的语句 console.info(i) 中的 ifor 循环中声明的 i,指向的是同一个 i,执行完最后一次循环时,i 的值就是 5。

    ES2015+ 方式

    新增的声明变量方式有:let、const。

    let 声明

    用法跟 var 类似,这种方式不同的地方有:

    1. 声明的变量,在 let 所在的代码块内有效。
    {
      let testLet = 1;
      var testVar = 2;
    }
    console.info('testVar=',testVar); // 2
    console.info('testLet=',testLet); // Uncaught ReferenceError: testLet is not defined
    
    1. 不会“变量提升”,要先声明后使用,否则会报错。
    console.info('testLet=',testLet); // Uncaught ReferenceError: testLet is not defined
    let testLet = 1;
    

    这种过早访问 let 声明的引用导致的 ReferenceError 严格说叫做“暂时死亡区”(Temporal Dead Zone,TDZ)错误。这种情况下,使用 typeof 就会有问题。

    console.info(typeof testVar);
    console.info(typeof testLet);
    var testVar = '123';
    var testLet = 123; // Uncaught ReferenceError: testLet is not defined
    
    1. 同一作用域内,不允许重复声明同一个变量。
    let testLet = 1;
    let testLet = '123'; // Uncaught SyntaxError: Identifier 'testLet' has already been declared
    

    同样在 for 循环中使用时:

    function printNum() {
      var numArray = [];
      for(let i=0;i<5;i++) {
        numArray.push(function (){
          console.info(i);
        })
      }
      numArray[0]();
    }
    printNum(); // 0
    

    for 循环头部的 let i 为每次循环都重新声明了一个变量 i。头部的声明是一个作用域,循环体内是另外一个单独的作用域。

    for(let i=0;i<2;i++) {
      let i = '123';
      console.info(i);
    }
    // 123
    // 123
    

    const 声明

    这种形式的声明,是用于创建常量。常量不是对这个值本身的限制,而是对赋值的那个变量的限制。变量实际是指向一个内存地址,const 就对这个内存地址所保存的数据进行了限制。对于简单的数据(例如数值、字符串、布尔值),值就保存在那个内存地址中,就等同于常量。如果复合类型的数据(例如数组和对象),内存地址中保存的就是一个指向实际数据的指针,const 保证的是这个指针固定,这个指针实际指向的内容就不能控制了。

    const testConst = [1,2];
    testConst.push(3);
    console.info(testConst); // [1,2,3]
    

    这种方式的特点有:

    1. let 一样,所在的代码块内有效。
    {
      const TEST = "0.618";
    }
    console.info(TEST); // Uncaught ReferenceError: TEST is not defined
    
    1. 不会“变量提升”,要先声明且初始化后才能使用,否则会报错。同样存在“暂时死亡区”。
    const K = 1.13198824;
    console.info(K);
    const TEST;
    console.info(TEST);
    // SyntaxError: Missing initializer in const declaration
    
    1. 同 let 一样,同一作用域内,不允许重复声明同一个变量。

    选择那种方式?

    在目前的工作中,发现使用 const 的频率非常高,一方面可能是由于使用 react 不可变数据,另一方面是听说 JavaScript 引擎在某些情况下对 const 进行了更好的优化。理论上说,引擎如果了解这个变量的值或类型不会改变,那么它就可以取消某些可能的追踪。实际到底有没有,这没有找到相关的信息。

    在 stackoverflow 中也有类似的提问:Const in javascript? When to use it and is it necessary。还有一些文章中的描述,似乎想要用 const 来规范代码行为:必须要初始化。这种规范代码行为的方式感觉很奇怪,写代码很重要的一个功能就是清晰的表达你的意图,不仅仅对自己,也是对未来的维护者或合作者。可能有人觉得到时候如果要改数据,把 const 修改为 let 就可以了。这样也许可以达到目的,那么后来接手的人只要想修改数据,就把 const 修改为 let,这样子做真的好吗?

    从代码的可读性和可理解性上,个人认同的方式是:当你想表明这个变量不会改变时才使用 const,这样更加合理。

    参考资料

  • 相关阅读:
    强制数据类型转换之Number类型
    强制类型转换之String类型
    数据类型之字符串类型与Number类型
    favicon.ico是什么?
    什么是自幂数?
    JavaScript基础之变量的自增与自减
    CMD 命令
    那些看完很有同感的语句
    HTML5 canvas 元素
    HTML的多媒体属性
  • 原文地址:https://www.cnblogs.com/thyshare/p/12813625.html
Copyright © 2011-2022 走看看