LOADING...

加载过慢请开启缓存(浏览器默认开启)

loading

var-let-const 关键字

2021/11/23 JavaScript
  • 按照惯例,ECMAScript 标识符使用驼峰大小写形式。

  • ES5 增加了严格模式的概念,严格模式是一种不同的 JavaScript 解析和执行模型,所有现代浏览器都支持严格模式。

  • ES 变量是松散类型的,这意味着变量可以用于保存任何类型的数据,每个变量只不过是一个用于保存任意值的命名占位符;var 在 ES 的所有版本中都能使用,而 const 和 let 只能在 ES6 及以后的版本中使用。

  • var 关键字

    • var 可以定义任何类型的值,当其指定的变量未初始化时,变量值为 undefined;
    • 使用 var 在函数内部定义变量,其作用域为函数内部;若在函数内部省略 var 操作符,变量将成为全局变量(不推荐,在严格模式下给未声明的变量赋值,将会抛出 ReferenceError)。
    • 使用 var 声明变量时,变量声明会自动提升到函数作用域的顶部,即可以先使用,再声明;
    • 可以使用 var 反复多次声明同一个变量。
  • let 关键字

    • let 声明的范围是块作用域,而不是函数作用域;
    • let 不允许同一个块作用域中出现冗余声明;
    • 不允许 let 和 var 在同一作用域中多次声明同一个变量,因为这两个子声明的不是不同类型的变量,他们只是指出变量在相关作用域中如何存在,冗余声明会出现 SyntaxError: var name; let name //SyntaxError
    • let 声明的变量不会在作用域中被提升,即必须先声明再使用——在 let 声明之前的执行瞬间被称为“暂时性死区”;
    • let 在全局作用域下声明的变量不会成为 window 对象的属性,var 声明的变量会:
      var name = 'xiaoming';
      console.log(window.name);    //'xiaoming'
    
      let age = 10;
      console.log(window.age);    //undefined
    
    • 不可能检查前面是否使用过 let 声明过同名变量。使用 var 声明的时候,JavaScript 引擎会自动将多余的声明在作用域顶部合并为一个声明;但是 let 的作用域是块,所以不可能检查前面是否使用 let 声明过同名变量,所以也就不可能在没有声明的情况下声明它(if 和 try-catch 均不可以)。有如下例子:
      if (typeof name === 'undefined') {
          let name;    //如果 name 没被声明过,便声明它
                       //但此时的 name 被限制在 if 的作用域内部
      }
      name = 'xiaoming';    //此处相当于一个全局赋值
    
    • 使用 var 定义 for 循环中的迭代变量会渗透到循环体的外部,但使用 let 定义的迭代变量被限制在 for 循环的循环块内部;
    • 使用 let 定义的迭代变量,JavaScript 会为每个迭代循环声明一个新的迭代变量,每个循环引用不同的迭代变量实例,而使用 var 定义时,只会保存时循环结束时的变量值:
      for (var i = 0; i < 5; ++i) { 
         setTimeout(() => console.log(i), 0) 
      }    //输出 5 5 5 5 5
      
      for (let i = 0; i < 5; ++i) { 
         setTimeout(() => console.log(i), 0) 
      }    //输出 0 1 2 3 4
    
  • const 关键字

    • 声明变量时必须同时初始化变量,并且变量值不可修改;
    • 作用域为块;
    • const 声明的限制仅限于它指向的变量的引用,若 const 变量引用的是一个对象,则可以改变对象内部的属性;
    • const 不能用于声明迭代变量(迭代变量会自增)。
  • 限制自己只使用 let 和 const 有助于提升代码质量,因为变量有了明确的作用域、声明位置以及不变的值。