为什么catch子句有自己的词汇环境? [英] Why do catch clauses have their own lexical environment?

查看:118
本文介绍了为什么catch子句有自己的词汇环境?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下摘录来自ECMA-262 v5.1 (我最近看到的)在这个问题):

Consider the following excerpt from ECMA-262 v5.1 (which I recently saw in this question):


词法环境是一种规范类型,用于根据ECMAScript代码的词法嵌套结构定义标识符与特定变量和函数的关联。词汇环境由环境记录和外部词汇环境的可能空引用组成。通常,词汇环境与ECMAScript代码的某些特定语法结构相关联,例如TryStatement的FunctionDeclaration,WithStatement或Catch子句,并且每次评估此类代码时都会创建新的词法环境。

A Lexical Environment is a specification type used to define the association of Identifiers to specific variables and functions based upon the lexical nesting structure of ECMAScript code. A Lexical Environment consists of an Environment Record and a possibly null reference to an outer Lexical Environment. Usually a Lexical Environment is associated with some specific syntactic structure of ECMAScript code such as a FunctionDeclaration, a WithStatement, or a Catch clause of a TryStatement and a new Lexical Environment is created each time such code is evaluated.

我认为这意味着 catch 子句的主体会像函数那样提升自己的变量,但显然< a href =http://jsfiddle.net/PbYRs/ =nofollow noreferrer>情况并非如此:

I thought that meant the body of catch clauses would hoist its own variables like functions do, but apparently that's not the case:

var a = 1;
try {
    console.log(x); // ReferenceError
} catch(ex) {
    console.log(a); // 1, not undefined
    var a = 3;
}

有人知道为什么吗?另外,为什么 catch 子句需要自己的词法环境?

Does anybody know why? Also, why does a catch clause need its own lexical environment?

推荐答案

是的, catch 子句确实有自己的词法环境。查看在评估时发生的事情:它会创建一个新的(从当前的一个派生)并将异常标识符绑定到它。执行catch块时,当前执行上下文 LexicalEnvironment 切换到新的,而 VariableEnvironment >其环境记录包含由<$创建的绑定c $ c> VariableStatements 和 FunctionDeclarations )保持不变。

Yes, catch clauses indeed have their own Lexical Environments. Check out what happens when it is evaluated: It creates a new one (deriving from the current one) and binds the exception-identifier to it. When executing the catch block, the current Execution Context's LexicalEnvironment is switched to the new one, while the VariableEnvironment("whose environment record holds bindings created by VariableStatements and FunctionDeclarations") stays unchanged.

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 ,因此它将无法访问异常:


Fun fact: If you try to declare a function inside a catch clause (though syntactically invalid in a block, "function declaration statements" are often accepted), its scope will become the current VariableEnvironment so it will not be able to access the exception:

try {throw "some"} catch(x) { function y(){console.log(x, typeof x);} y(); }
                    // throws a ReferenceError for x   ^

(更新:这是在ES6中不再正确,其中块级函数声明有效并且在块范围内关闭)

这篇关于为什么catch子句有自己的词汇环境?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆