Following the previous article [series] Learning Environment Records from the ECMAScript Specification for execution context (Middle), Object Environment Record and Global Environment Record
Object Environment Record
The most core feature of Object Environment Record is that it has a binding Object. The Object Env binds all the string attributes of the Object as identifiers in the env, so that these identifiers can be directly used in the corresponding scope. Attributes that are not strings are not bound as identifiers.
- Env binds the binding object itself and inherited properties as identifiers
- Env’s identifier bindings are also changed by adding or subtracting a binding object attribute, and all new bindings are mutable (even if the attribute is not writable).
The Object Env has the following specialized fields:
The field names | An optional value | paraphrase |
---|---|---|
[[BindingObject]] | object | The binding Object mentioned above |
[[IsWithEnvironment]] | Boolean | Used to indicate whether the env iswith Statement created by |
The execution logic of the Object Environment Record method
HasBinding ( N )
- let: bindingObject = env.[[BindingObject]]
- let: foundBinding = HasProperty(bindingObject, N)
- If: foundBinding to false,
return
false. - if: envRec.[[IsWithEnvironment]] is false,
return
true - let: unscopables = Get(bindingObject, @@unscopables)
- If Type(unscopables) is Object, then:
- let: blocked = ToBoolean(? Get(unscopables, N))
- If: blocked to true,
return
false
return
true
Tc39.es /ecma262/#se…
@@unscopables is a built-in Symbol. For details, see developer.mozilla.org/zh-CN/docs/…
CreateMutableBinding ( N, D )
- let: bindingObject = env.[[BindingObject]]
return
DefinePropertyOrThrow(bindingObject, N, PropertyDescriptor { [[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: D }).
DefinePropertyOrThrow Object. DefineProperty method tc39.es/ ecMA262 /#se…
CreateImmutableBinding ( N, S )
Is not used in object env
InitializeBinding ( N, V )
- Call env.setMutableBinding (N, V, false)
SetMutableBinding ( N, V, S )
- let: bindingObject = env.[[BindingObject]]
- let: stillExists = HasProperty(bindingObject, N)
- If: stillExists is false and S is true, a ReferenceError is directly raised
return
Set(bindingObject, N, V, S)
A Set is an attribute written to an object. It can be described in tc39.es/ ECMA262 /#se…
GetBindingValue ( N, S )
- let: bindingObject = env.[[BindingObject]]
- let: value = HasProperty(bindingObject, N)
- If: value is false then:
- If: S to false,
return
undefined; Otherwise a ReferenceError is raised
- If: S to false,
return
Get(bindingObject, N)
DeleteBinding ( N )
In the Object Env, the binding name N can be deleted only if the bind object attribute is [[64x]] = true
- let: bindingObject = env.[[BindingObject]]
return
bindingObject.[[Delete]] (N)
[[Delete]] [tc39.es/ ecMA262 /#se…
HasThisBinding ( )
return
false
HasSuperBinding ( )
return
false
WithBaseObject ( )
- If: env.[[IsWithEnvironment]] is true,
return
env.[[BindingObject]] - else:
return
undefined
Global Environment Record
The Global Environment Record represents the outermost scope. It provides bindings for built-in Global objects, properties of Global objects, and all top-level declarations within script elements.
A Global Environment Record is logically a separate ENV, but in the standard definition, it is actually a combination of object Environment Record and Declarative Environment Record.
-
Object Environment Record contains all built-in global variables, NaN, undefined, Infinity, parseInt, parseFloat, etc. These are included in the binding of the Environment Record. Combined with the use of the with statement (which creates an object env), we can see why NaN can be written directly in code rather than global.nan. All of these attributes or methods can be referred to chapter 19 of the Standard (TC39.ES/ECMA262 /# SE…).
-
In addition to these built-in global variables, the Object Environment Record contains bindings declared by the following syntax: function declarations, Generator function declarations, async, asynchronous generator function declarations, and VAR declarations.
-
In addition to the above, other declarations in the global Environment are included in the Declarative Environment Record, such as the let, const, and class statements in the global Environment.
Fields and methods unique to the Global Environment Record
The Global Environment Record has the following additional fields:
The field names | An optional value | paraphrase |
---|---|---|
[[ObjectRecord]] | Object Environment Record | That is, the object Environment Record mentioned above |
[[GlobalThisValue]] | Object | This value in the global scope. The host environment may provide any object as this value |
[[DeclarativeRecord]] | Declarative Environment Record | The Declarative Environment Record mentioned above |
[[VarNames]] | String[] | Under the global scope byFunction declaration ,Generator function declaration ,Asynchronous function declaration (Async) ,Asynchronous Generator function declaration andThe var statement A list of the resulting binding names |
The Global Environment Record has the following additional methods:
Method names | paraphrase |
---|---|
GetThisBinding() | Returns the value of env’s this binding |
HasVarDeclaration (N) | Check if env exists with the name N and is passedFunction declaration ,Generator function declaration ,Asynchronous function declaration (Async) ,Asynchronous Generator function declaration andThe var statement The binding created |
HasLexicalDeclaration (N) | Determine if env has a binding named N that was created by a lexical declaration. Lexical declarations include let, const, class, and so on |
HasRestrictedGlobalProperty (N) | |
CanDeclareGlobalVar (N) | Determines whether CreateGlobalVarBinding(N) was successfully called |
CanDeclareGlobalFunction (N) | Determine CreateGlobalFunctionBinding (N) whether the call is successful |
CreateGlobalVarBinding(N, D) | The following is a separate introduction |
CreateGlobalFunctionBinding(N, V, D) | The following is a separate introduction |
First key here introduce CreateGlobalVarBinding (N, D) and CreateGlobalFunctionBinding (N, V, D) these two methods:
– CreateGlobalVarBinding(N, D)
Used to create a binding in the Object Environment Record component and initialize it with an alias N, the initial value being undefined. The binding is a mutable binding, and if D is true, the binding may be removed. In addition, the global object will have an attribute named N, which will also be assigned a value
This explains why variables declared by var in global scope can pass “global”. Variable name “to access
– CreateGlobalFunctionBinding(N, V, D)
Used to create and initialize a function binding in the Object Environment Record component, where V is the initialization binding value (that is, the bound function). The binding is a mutable binding, and if D is true, the binding may be removed. In addition, the global object will have an attribute named N whose value is the function V
Execution logic of the Global Environment Record method
HasBinding ( N )
- let: DclRec = env.[[DeclarativeRecord]]
- If: dclrec.hasbinding (N), returns true
- let: ObjRec = env.[[ObjectRecord]]
return
ObjRec.HasBinding(N)
CreateMutableBinding ( N, D )
- let: DclRec = env.[[DeclarativeRecord]]
- If: dclrec.hasbinding (N) is true and raises TypeError directly
return
DclRec.CreateMutableBinding(N, D).
CreateImmutableBinding ( N, S )
Similar to CreateMutableBinding, except that the CreateImmutableBinding method of DeclarativeRecord is called as the last step
InitializeBinding ( N, V )
- let: DclRec = env.[[DeclarativeRecord]]
- If: DclRec HasBinding (N) is true
return
DclRec.InitializeBinding ( N, V )
- Assert: If a binding named N exists, it must exist in the Object Environment Record
- let: ObjRec = env.[[ObjectRecord]]
return
ObjRec.InitializeBinding(N, V)
SetMutableBinding ( N, V, S )
- let: DclRec = env.[[DeclarativeRecord]]
- If: DclRec HasBinding (N) is true
return
DclRec.SetMutableBinding ( N, V, S )
- let: ObjRec = env.[[ObjectRecord]]
return
ObjRec.SetMutableBinding ( N, V, S )
GetBindingValue ( N, S )
This is similar to the SetMutableBinding method above, except that the GetBindingValue methods of DclRec and ObjRec are called, respectively
DeleteBinding ( N )
- let: DclRec = env.[[DeclarativeRecord]]
- If: DclRec HasBinding (N) is true
- return DclRec.DeleteBinding ( N )
- let: ObjRec = env.[[ObjectRecord]]
- let: globalObject = ObjRec.[[BindingObject]]
- let: existingProp = HasOwnProperty(globalObject, N)
- if: existingProp = true:
- let:status = ObjRec.DeleteBinding(N)
- : if the status is true:
- let: varNames = envRec.[[VarNames]]
- If N is an element of varNames, it is removed from varNames
return
status
return
true
HasThisBinding ( )
–return
true
Global env provides this binding
HasSuperBinding ( )
return
false
WithBaseObject ( )
return
undefined
Although there is an object env component in the Global env, this component is not created by the with statement, so undefined is always returned
GetThisBinding ( )
return
env.[[GlobalThisValue]]
HasVarDeclaration ( N )
- let: varDeclaredNames = envRec.[[VarNames]]
- If: varDeclaredNames contains N,
The return
true return
false
HasLexicalDeclaration ( N )
- let: DclRec = env.[[DeclarativeRecord]]
return
DclRec.HasBinding(N)
HasRestrictedGlobalProperty ( N )
Used to determine whether identifier N is a property of the Global object. This property cannot be overridden by a global lexical declaration
- let: ObjRec = env.[[ObjectRecord]]
- let: globalObject = ObjRec.[[BindingObject]]
- let: existingProp = globalObject.GetOwnProperty(N)
- If: existingProp = undefined,
return
false - If: existingProp.[[signals]] works without any additional control system.
return
false return
true
CanDeclareGlobalVar ( N )
- let: ObjRec = env.[[ObjectRecord]]
- let: globalObject = ObjRec.[[BindingObject]]
- let: hasProperty = HasOwnProperty(globalObject, N)
- If: hasProperty is true,
return
true return
IsExtensible(globalObject)
IsExtensible can be understood as Object. IsExtensible methods
CanDeclareGlobalFunction ( N )
- let: ObjRec = env.[[ObjectRecord]]
- let: globalObject = ObjRec.[[BindingObject]]
- let: existingProp = globalObject.GetOwnProperty(N)
- If: existingProp = undefined,return IsExtensible(globalObject)
- If: existingProp. [[Configurable]] is true,
return
true - ExistingProp has attribute Values {[[Writable]]: true, [[Enumerable]]: true },
return
true
–return
false
IsDataDescriptor(desc) is true if the attribute descriptor desc has neither writable nor value. Otherwise it is false
CreateGlobalVarBinding ( N, D )
This method creates a mutable binding in the Object Environment Record component of the Global Env and adds the identifier N to the [[varNames]] Record
- let: ObjRec = env.[[ObjectRecord]]
- let: globalObject = ObjRec.[[BindingObject]]
- let: hasProperty = HasOwnProperty(globalObject, N)
- let: extensible = IsExtensible(globalObject)
- If: hasProperty is false and extensible to true:
- Perform ObjRec. CreateMutableBinding (N, D)
- Perform ObjRec. InitializeBinding (N, undefined)
- let: varDeclaredNames = env.[[VarNames]]
- If: varDeclaredNames does not already contain N, add N to the varDeclaredNames record
return
CreateGlobalFunctionBinding ( N, V, D )
- let: ObjRec = env.[[ObjectRecord]]
- let: globalObject = ObjRec.[[BindingObject]]
- let: existingProp = globalObject.GetOwnProperty(N)
- If: exists prop is undefined or exists ingProp.[[64x]] works without any additional information.
- Let:descAttribute descriptor = PropertyDescriptor {[[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[64x]]: 64x}
- Otherwise:
- Let:desc= PropertyDescriptor {[[Value]]: V}
- Do: DefinePropertyOrThrow(globalObject, N, desc)
- Execute: Set(globalObject, N, V, false)
- let: varDeclaredNames = env.[[VarNames]]
- If: varDeclaredNames does not already contain N, add N to the varDeclaredNames record
return