Execution environments
Execution environments are an abstraction used by the ECMAScript specification (ECMA 262 3rd edition) to define the necessary behavior of an ECMAScript implementation. The specification is silent on how to implement execution environments. However, since the execution environment contains relevant properties that reference structures defined by the specification, objects with properties should be preserved (or even implemented) in the execution environment - even if the properties are not public **** properties.
All JavaScript code is executed in an execution environment. Global code (code that is executed as a built-in JS file, or code that is loaded on an HTML page)
is executed in what I'll call the "global execution environment", and each call to a function (possibly as a constructor) also has an associated execution environment. By
When a JavaScript function is called, it enters the appropriate execution environment. If another function is called (or the same function is called recursively), a new execution environment is created and the execution process remains in that environment for the duration of the function call. When the called function returns, the executable returns to the original execution environment. Thus, the running JavaScript code constitutes an execution environment stack.
In the process of creating an execution environment, a number of operations are performed in the order in which they are defined. First, in the execution environment of a function, an "active" object is created. The active object is another mechanism specified in the specification. It's called an object because it has named properties that can be accessed, but it doesn't have a prototype like a normal object (at least not a predefined one), and you can't refer to an active object directly through JavaScript code.
The next step in creating the execution environment for a function call is to create an arguments object, which is an array-like object that holds the arguments passed when the function is called, in integer-indexed array members. This object also has length and callee attributes (which are irrelevant to our discussion; see the specification for details). Then, a property called "arguments" is created for the active object, which references the arguments object created earlier.
Next, scopes are assigned to the execution environment. A scope consists of a list (chain) of objects. Each function object has an internal [[scope]] property (which we'll cover in more detail later), which also consists of a list (chain) of objects. The scope assigned to the execution environment of a function call consists of the list of objects (chain) referenced by the [[scope]] property of that function object, while the active object is added to the top of that list of objects (the front of the chain).
The process of "variable instantiation", as done by the so-called "mutable" objects in ECMA 262, then occurs. Except that the active object is used as the mutable object (it is important to note here: they are the same object). The formal parameters of the function are created as named attributes of the variable object, and if the function is called with the same parameters as the formal parameters, the values of the corresponding parameters are assigned to these named attributes (otherwise, the named attributes are assigned undefined values). For defined internal functions, properties of the same name are created for the variable object with the name used in its declaration, and the corresponding internal function is created as a function object and assigned to that property. The final step in variable instantiation is to create all local variables declared inside the function as named properties of the variable object.
Properties of mutable objects created from declared local variables are assigned undefined values during variable instantiation. Local variables are not truly instantiated until the code within the function is executed and the corresponding assignment expression is evaluated.
In fact, the active object with the arguments attribute and the variable object with the named attribute corresponding to the function's local variable are the same object. Therefore, the identifier arguments can be treated as a local variable of the function.