js在编译阶段发现的代码错误叫作“早期错误”(early error)。语法错误是早期错误的一种(如 a = ,
)。另外,语法正确但不符合语法规则的情况也存在。这些错误在代码执行之前是无法用 try..catch
来捕获的,相反,它们还会导致解析 / 编译失败。
例子:正则表达式常量中的语法。这里 js 语法没有问题,但非法的正则表达式也会产生早期错误:
var a = /+foo/; // 错误
语法规定赋值对象必须是一个标识符(identifier,或者 ES6 中的解构表达式),因此下面的42
会报错:
var a;
42 = a; // 错误!
ES5 规范的严格模式定义了很多早期错误。比如在严格模式中,函数的参数不能重名:
function foo(a,b,a) { } // 没问题
function bar(a,b,a) { "use strict"; } // 错误!
再如,对象常量不能包含多个同名属性:
(function(){
"use strict";
var a = {
b: 42,
b: 43
};
})();
提前使用变量
ES6 规范定义了一个新概念,叫作 TDZ(Temporal Dead Zone,暂时性死区)。 TDZ 指的是由于代码中的变量还没有初始化而不能被引用的情况。
{
a = 2; // ReferenceError!
let a;
}
a = 2
试图在let a
初始化a
之前使用该变量(其作用域在{ .. }
内),这里就是a
的TDZ,会产生错误。
对未声明变量使用 typeof
不会产生错误,但在 TDZ 中却会报错:
{
typeof a; // undefined
typeof b; // ReferenceError! (TDZ)
let b;
}