为什么catch子句有自己的词汇环境?(Why do catch clauses have thei

2019-07-20 09:47发布

请看下面的摘录从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条款需要自己的词汇环境呢?

Answer 1:

是的, catch条款确实有自己的词法环境。 检查出什么时,其被评估情况 :它创建一个新的(从当前导出),并结合异常的标识符到它。 当执行catch块,当前执行上下文的 LexicalEnvironment切换到新的一个,而VariableEnvironment (“ 其环境记录保存以创建绑定VariableStatementsFunctionDeclarations ”)保持不变。

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,在块级函数声明是有效的,接近超过该块范围)



文章来源: Why do catch clauses have their own lexical environment?