PCDotFan

To be an life & code artisan

Understanding ES6 - 块级变量

JavaScript 0 评

varlet 最大的区别在于其 作用域 不相同。前者属于「Function Scope 函数作用域」,后者则是「Block Scope 块级作用域」,具体来上一个例子:

    if (1) {
      let a = 0;
      a = 10;
    }
    console.log(a);

这段代码返回的错误是 ReferenceError: a is not defined。这是因为 let 只对其所在的 语句块 内产生作用,然而 console.logif 语句所包含的代码块之外。若想使其成功运行,可以这样改:

    let a = 0;
    if (1) {
      a = 10;
      console.log(a);
    }

此时 a 被正常打印,返回 10。这是因为 let a = 0 所在位置「没有语句块」,换言之:此时的 a 变量对全局生效。 那……var呢?上例子:

  if (1) {
      var a = 0;
      a = 10;
  }
  console.log(a);

此时 a 正常被打印为 10。这是因为var的作用域属于「函数作用域」,当然会正常生效。相较而言,以下代码就没办法正常运行了:

    function printVar() {
      var a = 5
      console.log(a);
    }
    if (1) {
      printVar(a); // 5
      a = 10; // ReferenceError: a is not defined
      console.log(a);
    }

Var 雷区

Javascript 对 var 的设计略略相当奇葩,即使用var声明的变量可以在声明之前使用(变量提升)。看代码:

    console.log(a); // undefined
    var a = 100;

没有报错,直接返回 undefined。实际上以上代码等价于:

    var a;
    console.log(a); // undefined
    a = 100;

使用 var 绝对,绝对会给调试增加很多不必要的麻烦。更糟糕的是——var 可以被重复定义:

    var a = 100;
    console.log(a); // 100
    var a = 200; 
    console.log(a); // 200

正常返回,没有报错。而 let 的出现即完全避开了 var 在设计上的 雷区:没有变量提升(实际上是存在 TDZ)、不能重复定义(否则报错)、作用域更加严谨等等。

var 既然这么一无是处,为什么要存在呢?

反正 Laracasts 的 Jeffery Way 是这样做的:

NEVER USE VAR!