Clarity on the difference between “LexicalEnvironment” and “VariableEnvironment” in ECMAScript/JavaScript

岁酱吖の 提交于 2019-11-29 04:35:58
Bergi

Both are components (of the same type) of Execution Contexts, but they serve distinct purposes (from the spec):

LexicalEnvironment

Identifies the Lexical Environment used to resolve identifier references made by code within this execution context.

VariableEnvironment

Identifies the Lexical Environment whose environment record holds bindings created by VariableStatements and FunctionDeclarations within this execution context.

The next paragraph explains why they need to be different:

When an execution context is created its LexicalEnvironment and VariableEnvironment components initially have the same value. The value of the VariableEnvironment component never changes while the value of the LexicalEnvironment component may change during execution of code within an execution context.

That does not happen often and usually both refer to the same Lexical Environment. A good example for a changing LexicalEnvironment is given in the question Why do catch clauses have their own lexical environment? - see §12.14. The other place I could find in the spec where this happens are With Statements (§12.10) where an Object Environment Record is dynamically used for the identifier resolution - yet variable/function declarations are static.

As far as I understand, those are just different names used to refer to the same type of entity (Lexical Environment). They have different names due to different purposes.

LexicalEnvironment is used to resolve identifiers while VariableEnvironment is used to declare variables and functions.

Both of them reference Lexical Environment (= Environment Record + optional outer Lexical Environment; aka scope chain) that's created for each execution context.

The LexicalEnvironment and VariableEnvironment components of an execution context are always Lexical Environments. When an execution context is created its LexicalEnvironment and VariableEnvironment components initially have the same value. The value of the VariableEnvironment component never changes while the value of the LexicalEnvironment component may change during execution of code within an execution context

Example in pseudo code:

// 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)

  })();

})();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!