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. Usually an Environment Record is associated with some specific syntactic structure of ECMAScript code such as a FunctionDeclaration, a BlockStatement, or a Catch clause of a TryStatement. Each time such code is evaluated, a new Environment Record is created to record the identifier bindings that are created by that code.
Every Environment Record has an [[OuterEnv]] field, which is either null or a reference to an outer Environment Record. This is used to model the logical nesting of Environment Record values. The outer reference of an (inner) Environment Record is a reference to the Environment Record that logically surrounds the inner Environment Record. An outer Environment Record may, of course, have its own outer Environment Record. An Environment Record may serve as the outer environment for multiple inner Environment Records. For example, if a FunctionDeclaration contains two nested FunctionDeclarations then the Environment Records of each of the nested functions will have as their outer Environment Record the Environment Record of the current evaluation of the surrounding function.
Environment Records are purely specification mechanisms and need not correspond to any specific artefact of an ECMAScript implementation. It is impossible for an ECMAScript program to directly access or manipulate such values.
A Function Environment Record corresponds to the invocation of an ECMAScript function object, and contains bindings for the top-level declarations within that function. It may establish a new this binding. It also captures the state necessary to support super method invocations.
An Object Environment Record is used to define the effect of ECMAScript elements such as WithStatement that associate identifier bindings with the properties of some object.
A Global Environment Record is used for Script global declarations. It does not have an outer environment; its [[OuterEnv]] is null. It may be prepopulated with identifier bindings and it includes an associated global object whose properties provide some of the global environment's identifier bindings. As ECMAScript code is executed, additional properties may be added to the global object and the initial properties may be modified.
The Environment Record abstract class includes the abstract specification methods defined in Table 14. These abstract methods have distinct concrete algorithms for each of the concrete subclasses.
Determine if an Environment Record has a binding for the String value N. Return true if it does and false if it does not.
CreateMutableBinding(N, D)
Create a new but uninitialized mutable binding in an Environment Record. The String value N is the text of the bound name. If the Boolean argument D is true the binding may be subsequently deleted.
CreateImmutableBinding(N, S)
Create a new but uninitialized immutable binding in an Environment Record. The String value N is the text of the bound name. If S is true then attempts to set it after it has been initialized will always throw an exception, regardless of the strict mode setting of operations that reference that binding.
InitializeBinding(N, V)
Set the value of an already existing but uninitialized binding in an Environment Record. The String value N is the text of the bound name. V is the value for the binding and is a value of any ECMAScript language type.
SetMutableBinding(N, V, S)
Set the value of an already existing mutable binding in an Environment Record. The String value N is the text of the bound name. V is the value for the binding and may be a value of any ECMAScript language type. Sis a Boolean flag. If S is true and the binding cannot be set throw a TypeError exception.
GetBindingValue(N, S)
Returns the value of an already existing binding from an Environment Record. The String value N is the text of the bound name. S is used to identify references originating in strict mode code or that otherwise require strict mode reference semantics. If S is true and the binding does not exist throw a ReferenceError exception. If the binding exists but is uninitialized a ReferenceError is thrown, regardless of the value of S.
DeleteBinding(N)
Delete a binding from an Environment Record. The String value N is the text of the bound name. If a binding for N exists, remove the binding and return true. If the binding exists but cannot be removed return false. If the binding does not exist return true.
HasThisBinding()
Determine if an Environment Record establishes a this binding. Return true if it does and false if it does not.
HasSuperBinding()
Determine if an Environment Record establishes a super method binding. Return true if it does and false if it does not. If it returns true it implies that the Environment Record is a Function Environment Record, although the reverse implication does not hold.
WithBaseObject()
If this Environment Record is associated with a with statement, return the with object. Otherwise, return undefined.
9.1.1.1 Declarative Environment Records
Each Declarative Environment Record is associated with an ECMAScript program scope containing variable, constant, let, class, module, import, and/or function declarations. A Declarative Environment Record binds the set of identifiers defined by the declarations contained within its scope.
9.1.1.1.1 HasBinding ( N )
The HasBinding concrete method of a Declarative Environment RecordenvRec takes argument N (a String) and returns a normal completion containing a Boolean. It determines if the argument identifier is one of the identifiers bound by the record. It performs the following steps when called:
If envRec has a binding for N, return true.
Return false.
9.1.1.1.2 CreateMutableBinding ( N, D )
The CreateMutableBinding concrete method of a Declarative Environment RecordenvRec takes arguments N (a String) and D (a Boolean) and returns a normal completion containingunused. It creates a new mutable binding for the name N that is uninitialized. A binding must not already exist in this Environment Record for N. If D is true, the new binding is marked as being subject to deletion. It performs the following steps when called:
Assert: envRec does not already have a binding for N.
Create a mutable binding in envRec for N and record that it is uninitialized. If D is true, record that the newly created binding may be deleted by a subsequent DeleteBinding call.
Return unused.
9.1.1.1.3 CreateImmutableBinding ( N, S )
The CreateImmutableBinding concrete method of a Declarative Environment RecordenvRec takes arguments N (a String) and S (a Boolean) and returns a normal completion containingunused. It creates a new immutable binding for the name N that is uninitialized. A binding must not already exist in this Environment Record for N. If S is true, the new binding is marked as a strict binding. It performs the following steps when called:
Assert: envRec does not already have a binding for N.
Create an immutable binding in envRec for N and record that it is uninitialized. If S is true, record that the newly created binding is a strict binding.
Return unused.
9.1.1.1.4 InitializeBinding ( N, V )
The InitializeBinding concrete method of a Declarative Environment RecordenvRec takes arguments N (a String) and V (an ECMAScript language value) and returns a normal completion containingunused. It is used to set the bound value of the current binding of the identifier whose name is N to the value V. An uninitialized binding for N must already exist. It performs the following steps when called:
Assert: envRec must have an uninitialized binding for N.
Set the bound value for N in envRec to V.
Record that the binding for N in envRec has been initialized.
Return unused.
9.1.1.1.5 SetMutableBinding ( N, V, S )
The SetMutableBinding concrete method of a Declarative Environment RecordenvRec takes arguments N (a String), V (an ECMAScript language value), and S (a Boolean) and returns either a normal completion containingunused or a throw completion. It attempts to change the bound value of the current binding of the identifier whose name is N to the value V. A binding for N normally already exists, but in rare cases it may not. If the binding is an immutable binding, a TypeError is thrown if S is true. It performs the following steps when called:
If envRec does not have a binding for N, then
If S is true, throw a ReferenceError exception.
Perform ! envRec.CreateMutableBinding(N, true).
Perform ! envRec.InitializeBinding(N, V).
Return unused.
If the binding for N in envRec is a strict binding, set S to true.
If the binding for N in envRec has not yet been initialized, then
Throw a ReferenceError exception.
Else if the binding for N in envRec is a mutable binding, then
Change its bound value to V.
Else,
Assert: This is an attempt to change the value of an immutable binding.
If S is true, throw a TypeError exception.
Return unused.
Note
An example of ECMAScript code that results in a missing binding at step 1 is:
functionf() { eval("var x; x = (delete x, 0);"); }
9.1.1.1.6 GetBindingValue ( N, S )
The GetBindingValue concrete method of a Declarative Environment RecordenvRec takes arguments N (a String) and S (a Boolean) and returns either a normal completion containing an ECMAScript language value or a throw completion. It returns the value of its bound identifier whose name is N. If the binding exists but is uninitialized a ReferenceError is thrown, regardless of the value of S. It performs the following steps when called:
If the binding for N in envRec is an uninitialized binding, throw a ReferenceError exception.
Return the value currently bound to N in envRec.
9.1.1.1.7 DeleteBinding ( N )
The DeleteBinding concrete method of a Declarative Environment RecordenvRec takes argument N (a String) and returns a normal completion containing a Boolean. It can only delete bindings that have been explicitly designated as being subject to deletion. It performs the following steps when called:
If the binding for N in envRec cannot be deleted, return false.
Remove the binding for N from envRec.
Return true.
9.1.1.1.8 HasThisBinding ( )
The HasThisBinding concrete method of a Declarative Environment RecordenvRec takes no arguments and returns false. It performs the following steps when called:
The HasSuperBinding concrete method of a Declarative Environment RecordenvRec takes no arguments and returns false. It performs the following steps when called:
The WithBaseObject concrete method of a Declarative Environment RecordenvRec takes no arguments and returns undefined. It performs the following steps when called:
Return undefined.
9.1.1.2 Object Environment Records
Each Object Environment Record is associated with an object called its binding object. An Object Environment Record binds the set of string identifier names that directly correspond to the property names of its binding object. Property keys that are not strings in the form of an IdentifierName are not included in the set of bound identifiers. Both own and inherited properties are included in the set regardless of the setting of their [[Enumerable]] attribute. Because properties can be dynamically added and deleted from objects, the set of identifiers bound by an Object Environment Record may potentially change as a side-effect of any operation that adds or deletes properties. Any bindings that are created as a result of such a side-effect are considered to be a mutable binding even if the Writable attribute of the corresponding property is false. Immutable bindings do not exist for Object Environment Records.
Object Environment Records created for with statements (14.11) can provide their binding object as an implicit this value for use in function calls. The capability is controlled by a Boolean [[IsWithEnvironment]] field.
Object Environment Records have the additional state fields listed in Table 15.
Indicates whether this Environment Record is created for a with statement.
9.1.1.2.1 HasBinding ( N )
The HasBinding concrete method of an Object Environment RecordenvRec takes argument N (a String) and returns either a normal completion containing a Boolean or a throw completion. It determines if its associated binding object has a property whose name is N. It performs the following steps when called:
Let bindingObject be envRec.[[BindingObject]].
Let foundBinding be ? HasProperty(bindingObject, N).
If foundBinding is false, return false.
If envRec.[[IsWithEnvironment]] is false, return true.
The CreateMutableBinding concrete method of an Object Environment RecordenvRec takes arguments N (a String) and D (a Boolean) and returns either a normal completion containingunused or a throw completion. It creates in an Environment Record's associated binding object a property whose name is N and initializes it to the value undefined. If D is true, the new property's [[Configurable]] attribute is set to true; otherwise it is set to false. It performs the following steps when called:
Let bindingObject be envRec.[[BindingObject]].
Perform ? DefinePropertyOrThrow(bindingObject, N, PropertyDescriptor { [[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: D }).
Return unused.
Note
Normally envRec will not have a binding for N but if it does, the semantics of DefinePropertyOrThrow may result in an existing binding being replaced or shadowed or cause an abrupt completion to be returned.
9.1.1.2.3 CreateImmutableBinding ( N, S )
The CreateImmutableBinding concrete method of an Object Environment Record is never used within this specification.
In this specification, all uses of CreateMutableBinding for Object Environment Records are immediately followed by a call to InitializeBinding for the same name. Hence, this specification does not explicitly track the initialization state of bindings in Object Environment Records.
9.1.1.2.5 SetMutableBinding ( N, V, S )
The SetMutableBinding concrete method of an Object Environment RecordenvRec takes arguments N (a String), V (an ECMAScript language value), and S (a Boolean) and returns either a normal completion containingunused or a throw completion. It attempts to set the value of the Environment Record's associated binding object's property whose name is N to the value V. A property named N normally already exists but if it does not or is not currently writable, error handling is determined by S. It performs the following steps when called:
Let bindingObject be envRec.[[BindingObject]].
Let stillExists be ? HasProperty(bindingObject, N).
If stillExists is false and S is true, throw a ReferenceError exception.
The GetBindingValue concrete method of an Object Environment RecordenvRec takes arguments N (a String) and S (a Boolean) and returns either a normal completion containing an ECMAScript language value or a throw completion. It returns the value of its associated binding object's property whose name is N. The property should already exist but if it does not the result depends upon S. It performs the following steps when called:
The DeleteBinding concrete method of an Object Environment RecordenvRec takes argument N (a String) and returns either a normal completion containing a Boolean or a throw completion. It can only delete bindings that correspond to properties of the environment object whose [[Configurable]] attribute have the value true. It performs the following steps when called:
Let bindingObject be envRec.[[BindingObject]].
Return ? bindingObject.[[Delete]](N).
9.1.1.2.8 HasThisBinding ( )
The HasThisBinding concrete method of an Object Environment RecordenvRec takes no arguments and returns false. It performs the following steps when called:
The HasSuperBinding concrete method of an Object Environment RecordenvRec takes no arguments and returns false. It performs the following steps when called:
The WithBaseObject concrete method of an Object Environment RecordenvRec takes no arguments and returns an Object or undefined. It performs the following steps when called:
If envRec.[[IsWithEnvironment]] is true, return envRec.[[BindingObject]].
Otherwise, return undefined.
9.1.1.3 Function Environment Records
A Function Environment Record is a Declarative Environment Record that is used to represent the top-level scope of a function and, if the function is not an ArrowFunction, provides a this binding. If a function is not an ArrowFunction function and references super, its Function Environment Record also contains the state that is used to perform super method invocations from within the function.
Function Environment Records have the additional state fields listed in Table 16.
If this Environment Record was created by the [[Construct]] internal method, [[NewTarget]] is the value of the [[Construct]]newTarget parameter. Otherwise, its value is undefined.
Function Environment Records support all of the Declarative Environment Record methods listed in Table 14 and share the same specifications for all of those methods except for HasThisBinding and HasSuperBinding. In addition, Function Environment Records support the methods listed in Table 17:
Assert: envRec.[[ThisBindingStatus]] is not lexical.
If envRec.[[ThisBindingStatus]] is initialized, throw a ReferenceError exception.
Set envRec.[[ThisValue]] to V.
Set envRec.[[ThisBindingStatus]] to initialized.
Return unused.
9.1.1.3.2 HasThisBinding ( )
The HasThisBinding concrete method of a Function Environment RecordenvRec takes no arguments and returns a Boolean. It performs the following steps when called:
If envRec.[[ThisBindingStatus]] is lexical, return false; otherwise return true.
9.1.1.3.3 HasSuperBinding ( )
The HasSuperBinding concrete method of a Function Environment RecordenvRec takes no arguments and returns a Boolean. It performs the following steps when called:
If envRec.[[ThisBindingStatus]] is lexical, return false.
If envRec.[[FunctionObject]].[[HomeObject]] is undefined, return false; otherwise return true.
Assert: envRec.[[ThisBindingStatus]] is not lexical.
If envRec.[[ThisBindingStatus]] is uninitialized, throw a ReferenceError exception.
Return envRec.[[ThisValue]].
9.1.1.3.5 GetSuperBase ( envRec )
The abstract operation GetSuperBase takes argument envRec (a Function Environment Record) and returns an Object, null, or undefined. It returns the object that is the base for super property accesses bound in envRec. The value undefined indicates that such accesses will produce runtime errors. It performs the following steps when called:
Let home be envRec.[[FunctionObject]].[[HomeObject]].
A Global Environment Record is used to represent the outer most scope that is shared by all of the ECMAScript Script elements that are processed in a common realm. A Global Environment Record provides the bindings for built-in globals (clause 19), properties of the global object, and for all top-level declarations (8.2.9, 8.2.11) that occur within a Script.