有人可以澄清这两者之间的区别是什么,因为它们存在于执行上下文中?我很难阅读ECMA 262 v 5规范并清楚地看到差异。
谢谢你,
两者都是执行上下文的组件(相同类型),但它们用于不同的目的(来自规范):
词汇环境
标识
Lexical Environment
用于解析此执行上下文中的代码所做的标识符引用。
可变环境
标识
Lexical Environment
其环境记录保存由此执行上下文中的 VariableStatements 和 FunctionDeclarations 创建的绑定。
下一段解释了为什么它们需要不同:
创建执行上下文时,它的 LexicalEnvironment 和 VariableEnvironment 组件最初具有相同的值。VariableEnvironment 组件的值永远不会改变,而 LexicalEnvironment 组件的值可能会在执行上下文中的代码执行期间发生变化。
这种情况并不经常发生,通常两者都指相同的Lexical Environment
. 问题Why do catch clauses have their own lexical environment?中给出了改变 LexicalEnvironment 的一个很好的例子。- 见第 12.14 节。我可以在规范中找到发生这种情况的另一个地方是With Statements
(§12.10),其中 anObject Environment Record
动态用于标识符解析 - 但变量/函数声明是静态的。
据我了解,这些只是用于指代同一类型实体(词法环境)的不同名称。由于用途不同,它们有不同的名称。
LexicalEnvironment
用于解析标识符,而VariableEnvironment
用于声明变量和函数。
它们都引用了为每个执行上下文创建的词法环境(= 环境记录 + 可选的外部词法环境;又名作用域链)。
执行上下文的 LexicalEnvironment 和 VariableEnvironment 组件始终是 Lexical Environments。创建执行上下文时,它的 LexicalEnvironment 和 VariableEnvironment 组件最初具有相同的值。VariableEnvironment 组件的值永远不会改变,而 LexicalEnvironment 组件的值可能会在执行上下文中的代码执行期间发生变化
伪代码示例:
// VariableEnvironment (global) = { __outer__: null }
// LexicalEnvironment = VariableEnvironment (global)
(function foo() {
// VariableEnvironment (A) = { x: undefined, __outer__: global }
// LexicalEnvironment = VariableEnvironment (A)
var x;
(function bar(){
// VariableEnvironment (B) = { y: undefined, __outer__: A }
// LexicalEnvironment = VariableEnvironment (B)
var y;
x = 2;
// VariableEnvironment (A) = { x: 2, __outer__: global }
// LexicalEnvironment is still the same as VariableEnvironment (B)
})();
})();