js在编译阶段发现的代码错误叫作“早期错误”(early error)。语法错误是早期错误的一种(如 a = ,)。另外,语法正确但不符合语法规则的情况也存在。这些错误在代码执行之前是无法用 try..catch 来捕获的,相反,它们还会导致解析 / 编译失败。
例子:正则表达式常量中的语法。这里 js 语法没有问题,但非法的正则表达式也会产生早期错误:

  1. var a = /+foo/; // 错误

语法规定赋值对象必须是一个标识符(identifier,或者 ES6 中的解构表达式),因此下面的42 会报错:

  1. var a;
  2. 42 = a; // 错误!

ES5 规范的严格模式定义了很多早期错误。比如在严格模式中,函数的参数不能重名:

  1. function foo(a,b,a) { } // 没问题
  2. function bar(a,b,a) { "use strict"; } // 错误!

再如,对象常量不能包含多个同名属性:

  1. (function(){
  2. "use strict";
  3. var a = {
  4. b: 42,
  5. b: 43
  6. };
  7. })();

提前使用变量

ES6 规范定义了一个新概念,叫作 TDZ(Temporal Dead Zone,暂时性死区)。 TDZ 指的是由于代码中的变量还没有初始化而不能被引用的情况。

  1. {
  2. a = 2; // ReferenceError!
  3. let a;
  4. }

a = 2试图在let a初始化a之前使用该变量(其作用域在{ .. }内),这里就是a的TDZ,会产生错误。
对未声明变量使用 typeof 不会产生错误,但在 TDZ 中却会报错:

  1. {
  2. typeof a; // undefined
  3. typeof b; // ReferenceError! (TDZ)
  4. let b;
  5. }