ES5 changed variable object(VO) to lexical environment. What's the motivation of such change since VO is already very obvious as perception?
I think variable objects are more analogous to environment records.
An Environment Record records the identifier bindings that are created within the scope of its associated Lexical Environment.
In ES5 there are two different kinds of 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.
So the question would be why declarative environment records were introduced instead of only using object environment records just like ES3 variable objects. The difference is that declarative environment records can have immutable bindings:
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.
Immutable bindings don't have a direct equivalent in objects. A property can be defined as both non-configurable and non-writable, becoming immutable. However,
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.
But you can't have an uninitialized property. If you define a non-configurable non-writable property with value undefined, then you won't be able to initialize it to the desired value.
I don't think it's possible to have uninitialized immutable bindings in ES5. CreateImmutableBinding is only used in Declaration Binding Instantiation and Function Definition, and in both cases it's immediately initialized with InitializeImmutableBinding.
But possibly this was done to allow uninitialized immutable bindings as extensions of the language, like the JavaScript 1.5 const
. Or maybe they already had in mind ES6 const
.