This series of articles introduces chapter 9 of the ES standard to understand the execution context and related concepts we often talk about from a standards perspective. The content of this chapter is very large, so it will be divided into several articles. This chapter first introduces Environment Records. This paper uses the latest standard document (2021-05-06), linked as follows: TC39.es/ECMA262 /

What is an Environment Record

It is a Record structure (Wiki), which can refer to the Record type of TS. It can be used to implement mapping relationships.

Environment Record 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

To summarize a few points from the definition:

  • Environment Record is only an abstract type in the standard, which cannot be obtained in the concrete implementation
  • Its role is to define associations between identifiers and specific variables or functions based on the lexical nesting structure of the code

In short, when an identifier appears in our code, the identifier must represent a variable or function, and the Environment Record is used to Record this association.

The occurrence of an Environment Record is usually associated with a specific syntax structure, for example: Modules, function declarations, code blocks, catch statements, with statements, and so on. Once this type of code is parsed, an Environment Record is created to Record the binding of identifiers generated by this code.

The Env abbreviation may be used later to represent an Environment Record

From Environment Record to Environment Records

Each Environment Record has a [[OuterEnv]] field, which can be either null or a reference to an external Env, to indicate logical nesting between enVNs.

[[OuterEnv]] refers to an external Env, and the OuterEnv logically surrounds the inner Env with [[OuterEnv]] fields, and so on, creating a chain that can be used later in identifier parsing. For example, we have the following code in the global environment:

function outer() {
    function inner1() {}function inner2() {}}Copy the code

In this case, we can roughly represent the nested relationship between enVs as shown below (just roughly, since context and Env are not one-to-one) :

The type of Environment Record

As mentioned earlier, enVs can be created with different syntax structures, and there are some differences between them. The standard uses an object-oriented form to represent the different enVs and their relationships: Environment Record is an abstract class with three concrete subclasses: Declarative Environment Record, object Environment Record, global Environment Record. Function Environment Record and Module Environment Record are subclasses of Declarative Environment Record. We can use UML to express this briefly:

declarative Environment Record

Defines the effects of binding identifiers directly to ECMAScript language type values in script code, such as function declarations, var variable declarations, and catch statements.

function Environment Record

Related to function object calls in scripts, including top-level bindings inside functions; Among other things, it might form a new this binding and support the necessary super method calls.

module Environment Record

Contains bindings at the top level within the module, which is the ES6 Module, as well as explicit bindings introduced by import statements within the module. Its [[OuterEnv]] points to the global Env

object Environment Record

Define the effect of binding an identifier to an object’s property in script code, such as the with statement. However, since the with statement is disabled in strict mode, the object Environment Record will not be covered in detail in subsequent articles.

global Environment Record

Global declaration for a script, whose [[OuterEnv]] is NULL; It is pre-populated with bindings and contains a global object whose properties provide partial identifier bindings. For example, if we write console.log(name) in the global code, we will not get an error because name is an attribute of the global object window, and this attribute is prepopulated in the Global Env, so it can be accessed directly. Of course, the same is true for location,history, etc.

Abstract method of Environment Record

As mentioned above, the Environment Record can be thought of as an abstract class that contains the abstract methods that each concrete subclass must implement. These methods are all operations related to binding around identifiers, including:

methods meaning
HasBinding(N) Returns whether Env has a binding to the string value N
CreateMutableBinding(N, D) Create an uninitialized mutable binding with the string N representing the name of the binding. D is a Boolean value that indicates whether the binding can be deleted
CreateImmutableBinding(N, S) Create an immutable binding of Uninitialized with the string N representing the name of the binding. S is a Boolean value. If true, if set after the binding has been initialized, an error will be thrown
InitializeBinding(N, V) Set a value for a binding that was created but is uninitialized. The string N represents the name of the binding. V stands for binding value, which can be any ECMAScript language type
SetMutableBinding(N, V, S) Set value for an existing mutable binding, with the string N representing the name of the binding; V stands for binding value, which can be any ECMAScript language type; S is a Boolean value, and if true, an error will be thrown if the binding cannot be set
GetBindingValue(N, S) Gets the value of the binding name N, S is a Boolean value, and if true, an error will be reported if the binding does not exist or is not initialized
DeleteBinding(N) Delete the binding name N, and return true if the binding exists and can be removed, false otherwise; Return false if the binding does not exist
HasThisBinding() Check if Env created the this binding
HasSuperBinding() Determines whether Env has created a super binding
WithBaseObject() If Env is associated with the with statement, return the object of the with statement. Otherwise return undefined

Different types of specific Environment Records will have different logic when implementing these methods, and additional attributes or methods may be added, which we will cover in detail in the next article.