请看下面的摘录从ECMA-262 V5.1 (这是我最近在看到这个问题 ):
甲词法环境是用于定义标识符基于的ECMAScript的代码的词法嵌套结构中的特定的变量和函数的相关联的规范类型。 甲词法环境由一个环境记录和可能空引用到外词法环境的。 一般一个词法环境与ECMAScript的的代码一些特定的句法结构相关联,例如一个FunctionDeclaration,一个WithStatement或TryStatement的catch子句和一个新的词法环境每一个这样的代码被评估时间被创建。
我认为这意味着身体catch
象函数的功能,但显然条款将扯起了自己的变量, 这是不是这样的 :
var a = 1;
try {
console.log(x); // ReferenceError
} catch(ex) {
console.log(a); // 1, not undefined
var a = 3;
}
有谁知道为什么吗? 另外,为什么一catch
条款需要自己的词汇环境呢?
是的, catch
条款确实有自己的词法环境。 检查出什么时,其被评估情况 :它创建一个新的(从当前导出),并结合异常的标识符到它。 当执行catch块,当前执行上下文的 LexicalEnvironment
切换到新的一个,而VariableEnvironment
(“ 其环境记录保存以创建绑定VariableStatements
和FunctionDeclarations
”)保持不变。
console.log(a); // undefined - declared from within the catch,
// but in the current VariableEnvironment
a = 1;
console.log(typeof ex); // undefined - no binding
try {
console.log(ex); // a ReferenceError in this LexicalEnvironment
} catch (ex) { // introducing the new LexicalEnvironment
console.log(ex); // …and it works here!
var a = 3; // variable declaration
}
有趣的事实:如果你试图声明一个内部函数catch
从句(虽然在一个块语法无效,“函数的声明语句”经常接受),其范围将成为当前VariableEnvironment
,所以它不会能够访问除外:
try {throw "some"} catch(x) { function y(){console.log(x, typeof x);} y(); }
// throws a ReferenceError for x ^
(更新:这不再是真实的ES6,在块级函数声明是有效的,接近超过该块范围)