• Author: Chen Da Yu Tou
  • Making: KRISACHAN
  • Link: github.com/YvetteLau/S…
  • Background: Recently senior front end engineer Liu Xiaoxi opened a front end related topic on Github every weekday repO, with the mentality of learning I also participate in it, the following is my answer, if there is any wrong place, very welcome to point out.

Lexical environment

Lexical Environment is the ECMAScript code Environment.

It consists of an Environment Record and external references.

It is created dynamically from ECMAScript code.

An environment record is bound to its associated lexical environment. It is divided into 5 categories as follows:

  • Declarative Environment Records: Declarative Environment Records bind variable declarations, which include: Var, let, const, class, module, import, function.
  • Object Environment Records: Records the addition, deletion, modification, and query of each Object.
  • Function Environment Records: Function Environment Records the details of each Function scope and context.
  • Global Environment Records: Global Environment Records are used to represent the outermost scope shared by all ECMAScript Script elements. The global environment record provides bindings for built-in global variables, properties of global objects, and all top-level declarations that occur in the script.
  • Module Environment Records: Module Environment Records are used to indicate the external scope and bindings of ECMAScript modules.

Lexical environments are divided into three categories:

  • Global environment: A global environment is a lexical environment with no external environment. The reference to the global environment’s external environment is null. The EnvironmentRecord of the Global Environment can bind variables and associate corresponding global objects.
  • Module Environment: The Module environment is also a lexical environment that contains the bindings declared at the top level of the module. It also contains bindings for explicit module imports. The external environment of a module environment is the Global environment.
  • Function environment: The function environment is also a lexical environment that corresponds to the invocation of ECMAScript function objects. The function environment can create a new binding. The function environment also supports the state required for super calls.

Execution Context

Execution Context is the context of the ECMAScript code Runtime.

Only one Execution context can be running at a time. This is called running execution Context.

The Execution Context stack is used to track execution Contexts.

The running Execution Context is always the top-level element of this stack.

A new execution context is created whenever control is transferred from executable code associated with the execution context currently running to executable code independent of that execution context.

The newly created execution context is pushed onto the stack and becomes the running execution context.

State Components for all execution contexts

component role
code evaluation state Used to determine the state of the current execution context
Function Determines the state of the current execution context, if the current context is a function, the context is the function object, otherwise null
Realm Related code is accessed from itECMAScriptRealm records of code.
ScriptOrModule Determine the current code environment, if there is no script or module environment, as inInitializeHostDefinedRealm(Native method)As in the case of the original execution context created innull.

Scope chain

A scope is responsible for collecting and maintaining a series of queries made up of all declared identifiers (variables) and enforcing a very strict set of rules that determine access to these identifiers by currently executing code. JavaScript you Don’t Know (Volume 1)

From the above two topics, we know that in addition to the global scope, each scope is always connected to one or more scopes behind it, thus forming a scope chain. The global scope does not have any parents, which also makes sense because it is at the top of the hierarchy.

Let’s look at the following code:

const bestAvenger = "Iron man";
function a() {
  const bestActor = "Neymar";
  console.log(bestAvenger); // output:Iron man
    
  function c() {
    const bestProgrammingLanguage = "Html";
    console.log(bestActor); // output:Neymar
    b();
  }
  c();
}
function b() {
  console.log(bestProgrammingLanguage); //**not defined error**
}
a();
Copy the code

The above code will report the following error: bestProgrammingLanguage is not defined.

As mentioned above, Scope chains are always created lexically. The parent node of a scope is defined by the lexical or physical location of the execution context (function) in the code.

The Scope chain of the code above is as follows:

Lexical environment The scope chain
G in global scope G = G
A. G A = A + G
B G B = B + G
A under G, C under A C=C+A => C+A+G

In fact, it can be summed up as:

  • Whenever the compiler encounters a variable or object, it traverses the entire Scope chain of the current execution context, traversing the Prototype chain if it is not found there, and throwing undefined errors if it is not found there either.
  • The compiler creates the scope of a function by looking at its position in the code.
  • The compiler creates Scope chains, with the Global Scope at the top of the hierarchy.
  • When a variable is used in code, the compiler looks back at the scope chain and throws an undefined error if it is not found.

The resources

  1. ECMA document
  2. Javascript Scope Chain and Execution Context simplified

If you like to discuss technology, or have any comments or suggestions on this article, you are welcome to add yu Tou wechat friends to discuss. Of course, Yu Tou also hopes to talk about life, hobbies and things with you. You can also scan your wechat account to subscribe to more exciting content.