There are three types of ECMAScript executable code:
Global code is source text that is treated as an ECMAScript Program. The global code of a particular Program does not include any source text that is parsed as part of a FunctionBody.
Eval code is the source text supplied to the built-in eval
function. More precisely, if the
parameter to the built-in eval
function is a String, it is treated as an ECMAScript Program. The eval
code for a particular invocation of eval
is the global code portion of that Program.
Function code is source text that is parsed as part of a FunctionBody. The function code of a
particular FunctionBody does not include any source text that is parsed as part of a nested FunctionBody.
Function code also denotes the source text supplied when using the built-in Function
object as a
constructor. More precisely, the last parameter provided to the Function
constructor is converted to a String
and treated as the FunctionBody. If more than one parameter is provided to the Function
constructor,
all parameters except the last one are converted to Strings and
concatenated together, separated by commas. The resulting
String is interpreted as the FormalParameterList for the FunctionBody defined by the last parameter. The
function code for a particular instantiation of a Function
does not include any source text that is parsed as
part of a nested FunctionBody.
An ECMAScript Program syntactic unit may be processed using either unrestricted or strict mode syntax and semantics. When processed using strict mode the three types of ECMAScript code are referred to as strict global code, strict eval code, and strict function code. Code is interpreted as strict mode code in the following situations:
Global code is strict global code if it begins with a Directive Prologue that contains a Use Strict Directive (see 14.1).
Eval code is strict eval code if it begins with a Directive Prologue that contains a Use Strict Directive or if the call to eval is a direct call (see 15.1.2.1.1) to the eval function that is contained in strict mode code.
Function code that is part of a FunctionDeclaration, FunctionExpression, or accessor PropertyAssignment is strict function code if its FunctionDeclaration, FunctionExpression, or PropertyAssignment is contained in strict mode code or if the function code begins with a Directive Prologue that contains a Use Strict Directive.
Function code that is supplied as the last argument to the built-in Function constructor is strict function code if the last argument is a String that when processed as a FunctionBody begins with a Directive Prologue that contains a Use Strict Directive.
A Lexical Environment 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. A Lexical Environment consists of an Environment Record and a possibly null reference to an outer Lexical Environment. Usually a Lexical Environment is associated with some specific syntactic structure of ECMAScript code such as a FunctionDeclaration, a WithStatement, or a Catch clause of a TryStatement and a new Lexical Environment is created each time such code is evaluated.
An Environment Record records the identifier bindings that are created within the scope of its associated Lexical Environment.
The outer environment reference is used to model the logical nesting of Lexical Environment values. The outer reference of a (inner) Lexical Environment is a reference to the Lexical Environment that logically surrounds the inner Lexical Environment. An outer Lexical Environment may, of course, have its own outer Lexical Environment. A Lexical Environment may serve as the outer environment for multiple inner Lexical Environments. For example, if a FunctionDeclaration contains two nested FunctionDeclarations then the Lexical Environments of each of the nested functions will have as their outer Lexical Environment the Lexical Environment of the current execution of the surrounding function.
Lexical Environments and Environment Record values 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.
There are two kinds of Environment Record values used in this specification: declarative environment records and object environment records. Declarative environment records are used to define the effect of ECMAScript language syntactic elements such as FunctionDeclarations, VariableDeclarations, and Catch clauses that directly associate identifier bindings with ECMAScript language values. Object environment records are used to define the effect of ECMAScript elements such as Program and WithStatement that associate identifier bindings with the properties of some object.
For specification purposes Environment Record values can be thought of as existing in a simple object-oriented hierarchy where Environment Record is an abstract class with two concrete subclasses, declarative environment record and object environment record. The abstract class includes the abstract specification methods defined in Table 17. These abstract methods have distinct concrete algorithms for each of the concrete subclasses.
Method | Purpose |
---|---|
HasBinding(N) | Determine if an environment record has a binding for an identifier. Return true if it does and false if it does not. The String value N is the text of the identifier. |
CreateMutableBinding(N, D) | Create a new mutable binding in an environment record. The String value N is the text of the bound name. If the optional Boolean argument D is true the binding is may be subsequently deleted. |
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. S is a Boolean flag. If S is true and the binding cannot be set throw a TypeError exception. S is used to identify strict mode references. |
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 strict mode references. If S is true and the binding does not exist or is uninitialised throw a ReferenceError exception. |
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. |
ImplicitThisValue() | Returns the value to use as the this value on calls to function objects that are obtained as binding values from this environment record. |
Each declarative environment record is associated with an ECMAScript program scope containing variable and/or function declarations. A declarative environment record binds the set of identifiers defined by the declarations contained within its scope.
In addition to the mutable bindings supported by all Environment Records, declarative environment records also provide for immutable bindings. An immutable binding is one where the association between an identifier and a value may not be modified once it has been established. Creation and initialisation of immutable binding are distinct steps so it is possible for such bindings to exist in either an initialised or uninitialised state. Declarative environment records support the methods listed in Table 18 in addition to the Environment Record abstract specification methods:
Method | Purpose |
---|---|
CreateImmutableBinding(N) | Create a new but uninitialised immutable binding in an environment record. The String value N is the text of the bound name. |
InitializeImmutableBinding(N,V) | Set the value of an already existing but uninitialised immutable 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. |
The behaviour of the concrete specification methods for Declarative Environment Records is defined by the following algorithms.
The concrete environment record method HasBinding for declarative environment records simply determines if the argument identifier is one of the identifiers bound by the record:
The concrete Environment Record method CreateMutableBinding for declarative environment records creates a new mutable binding for the name N that is initialised to the value undefined. A binding must not already exist in this Environment Record for N. If Boolean argument D is provided and has the value true the new binding is marked as being subject to deletion.
The concrete Environment Record method SetMutableBinding for declarative environment records attempts to change the bound value of the current binding of the identifier whose name is the value of the argument N to the value of argument V. A binding for N must already exist. If the binding is an immutable binding, a TypeError is thrown if S is true.
The concrete Environment Record method GetBindingValue for declarative environment records simply returns the value of its bound identifier whose name is the value of the argument N. The binding must already exist. If S is true and the binding is an uninitialised immutable binding throw a ReferenceError exception.
The concrete Environment Record method DeleteBinding for declarative environment records can only delete bindings that have been explicitly designated as being subject to deletion.
Declarative Environment Records always return undefined as their ImplicitThisValue.
The concrete Environment Record method CreateImmutableBinding for declarative environment records creates a new immutable binding for the name N that is initialised to the value undefined. A binding must not already exist in this environment record for N.
The concrete Environment Record method InitializeImmutableBinding for declarative environment records is used to set the bound value of the current binding of the identifier whose name is the value of the argument N to the value of argument V. An uninitialised immutable binding for N must already exist.
Each object environment record is associated with an object called its binding object. An object environment record binds the set of identifier names that directly correspond to the property names of its binding object. Property names that are not 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 has the value false. Immutable bindings do not exist for object environment records.
Object environment records can be configured to provide their binding object as an implicit this value for use in function calls. This capability is used to specify the behaviour of With Statement (12.10) induced bindings. The capability is controlled by a provideThis Boolean value that is associated with each object environment record. By default, the value of provideThis is false for any object environment record.
The behaviour of the concrete specification methods for Object Environment Records is defined by the following algorithms.
The concrete Environment Record method HasBinding for object environment records determines if its associated binding object has a property whose name is the value of the argument N:
The concrete Environment Record method CreateMutableBinding for object environment records creates in an environment record's associated binding object a property whose name is the String value and initialises it to the value undefined. A property named N must not already exist in the binding object. If Boolean argument D is provided and has the value true the new property’s [[Configurable]] attribute is set to true, otherwise it is set to false.
The concrete Environment Record method SetMutableBinding for object environment records attempts to set the value of the environment record's associated binding object's property whose name is the value of the argument N to the value of argument V. A property named N should already exist but if it does not or is not currently writable, error handling is determined by the value of the Boolean argument S.
The concrete Environment Record method GetBindingValue for object environment records returns the value of its associated binding object's property whose name is the String value of the argument identifier N. The property should already exist but if it does not the result depends upon the value of the S argument:
The concrete Environment Record method DeleteBinding for object environment records can only delete bindings that correspond to properties of the environment object whose [[Configurable]] attribute have the value true.
Object Environment Records return undefined as their ImplicitThisValue unless their provideThis flag is true.
The following abstract operations are used in this specification to operate upon lexical environments:
The abstract operation GetIdentifierReference is called with a Lexical Environment lex, an identifier String name, and a Boolean flag strict. The value of lex may be null. When called, the following steps are performed:
true
, then
When the abstract operation NewDeclarativeEnvironment is called with either a Lexical Environment or null as argument E the following steps are performed:
When the abstract operation NewObjectEnvironment is called with an Object O and a Lexical Environment E (or null) as arguments, the following steps are performed:
The global environment is a unique Lexical Environment which is created before any ECMAScript code is executed. The global environment's Environment Record is an object environment record whose binding object is the global object (15.1). The global environment's outer environment reference is null.
As ECMAScript code is executed, additional properties may be added to the global object and the initial properties may be modified.
When control is transferred to ECMAScript executable code, control is entering an execution context. Active execution contexts logically form a stack. The top execution context on this logical stack is the running execution context. A new execution context is created whenever control is transferred from the executable code associated with the currently running execution context to executable code that is not associated with that execution context. The newly created execution context is pushed onto the stack and becomes the running execution context.
An execution context contains whatever state is necessary to track the execution progress of its associated code. In addition, each execution context has the state components listed in Table 19.
Component | Purpose |
---|---|
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. |
ThisBinding | The value associated with the this keyword within ECMAScript code associated with this 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.
In most situations only the running execution context (the top of the execution context stack) is directly manipulated by algorithms within this specification. Hence when the terms “LexicalEnvironment”, “VariableEnvironment” and “ThisBinding” are used without qualification they are in reference to those components of the running execution context.
An execution context is purely a specification mechanism and need not correspond to any particular artefact of an ECMAScript implementation. It is impossible for an ECMAScript program to access an execution context.
Identifier resolution is the process of determining the binding of an Identifier using the LexicalEnvironment of the running execution context. During execution of ECMAScript code, the syntactic production PrimaryExpression : Identifier is evaluated using the following algorithm:
The result of evaluating an identifier is always a value of type Reference with its referenced name component equal to the Identifier String.
Evaluation of global code or code using the eval function (15.1.2.1) establishes and enters a new execution context. Every invocation of an ECMAScript code function (13.2.1) also establishes and enters a new execution context, even if a function is calling itself recursively. Every return exits an execution context. A thrown exception may also exit one or more execution contexts.
When control enters an execution context, the execution context's ThisBinding is set, its VariableEnvironment and initial LexicalEnvironment are defined, and declaration binding instantiation (10.5) is performed. The exact manner in which these actions occur depend on the type of code being entered.
The following steps are performed when control enters the execution context for global code:
The following steps are performed to initialise a global execution context for ECMAScript code C:
The following steps are performed when control enters the execution context for eval code:
The eval code cannot instantiate variable or function bindings in the variable environment of the calling context that invoked the eval if either the code of the calling context or the eval code is strict code. Instead such bindings are instantiated in a new VariableEnvironment that is only accessible to the eval code.
The following steps are performed when control enters the execution context for function code contained in function object F, a caller provided thisArg, and a caller provided argumentsList:
Every execution context has an associated VariableEnvironment. Variables and functions declared in ECMAScript code evaluated in an execution context are added as bindings in that VariableEnvironment's Environment Record. For function code, parameters are also added as bindings to that Environment Record.
Which Environment Record is used to bind a declaration and its kind depends upon the type of ECMAScript code executed by the execution context, but the remainder of the behaviour is generic. On entering an execution context, bindings are created in the VariableEnvironment as follows using the caller provided code and, if it is function code, argument List args:
"arguments"
as the argument.arguments
" as
the argument.arguments
" and
argsObj as arguments.arguments
" as the
argument.arguments
", argsObj, and
false as arguments.When control enters an execution context for function code, an arguments object is created unless (as specified in 10.5) the identifier arguments
occurs as an Identifier in the
function's FormalParameterList or occurs as the Identifier of a VariableDeclaration or FunctionDeclaration contained in the function code.
The arguments object is created by calling the abstract operation CreateArgumentsObject with arguments func the function object whose code is to be evaluated, names a List containing the function’s formal parameter names, args the actual arguments passed to the [[Call]] internal method, env the variable environment for the function code, and strict a Boolean that indicates whether or not the function code is strict code. When CreateArgumentsObject is called the following steps are performed:
new Object()
where
Object
is the standard built-in constructor with that namecallee
", the property descriptor
{[[Value]]: func, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true},
and false as arguments."caller"
,
PropertyDescriptor {[[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false,
[[Configurable]]: false}, and false."callee"
,
PropertyDescriptor {[[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false,
[[Configurable]]: false}, and false.The abstract operation MakeArgGetter called with String name and environment record env creates a function object that when executed returns the value bound for name in env. It performs the following steps:
return
", name, and
";
".The abstract operation MakeArgSetter called with String name and environment record env creates a function object that when executed sets the value bound for name in env. It performs the following steps:
The [[Get]] internal method of an arguments object for a non-strict mode function with formal parameters when called with a property name P performs the following steps:
"caller"
and v is a strict mode Function object, throw a TypeError
exception.The [[GetOwnProperty]] internal method of an arguments object for a non-strict mode function with formal parameters when called with a property name P performs the following steps:
The [[DefineOwnProperty]] internal method of an arguments object for a non-strict mode function with formal parameters when called with a property name P, Property Descriptor Desc, and Boolean flag Throw performs the following steps:
The [[Delete]] internal method of an arguments object for a non-strict mode function with formal parameters when called with a property name P and Boolean flag Throw performs the following steps:
NOTE 1 For non-strict mode functions the array index (defined in 15.4) named data properties of an arguments object whose numeric name values are less than the number of formal parameters of the corresponding function object initially share their values with the corresponding argument bindings in the function's execution context. This means that changing the property changes the corresponding value of the argument binding and vice-versa. This correspondence is broken if such a property is deleted and then redefined or if the property is changed into an accessor property. For strict mode functions, the values of the arguments object's properties are simply a copy of the arguments passed to the function and there is no dynamic linkage between the property values and the formal parameter values.
NOTE 2 The ParameterMap object and its property values are used as a device for specifying the arguments object correspondence to argument bindings. The ParameterMap object and the objects that are the values of its properties are not directly accessible from ECMAScript code. An ECMAScript implementation does not need to actually create or use such objects to implement the specified semantics.
NOTE 3 Arguments objects for strict mode functions define non-configurable accessor properties named "caller
" and "callee
" which throw a TypeError exception on access. The "callee
" property has a more specific meaning for non-strict mode functions and a "caller
" property has historically been provided as an implementation-defined extension by some ECMAScript implementations. The strict mode definition of these properties exists to ensure that neither of them is defined in any other manner by conforming ECMAScript implementations.