Why was the variable object changed to the lexical environment in ES5?

ES5 changed a variable object (VO) into a lexical environment. What is the motivation for such a change after VO is already very obvious as perception?

+5
source share
2 answers

I think variable objects are more like environment records .

In the environment record, the created identifier bindings are recorded as part of their associated lexical environment.

There are two different kinds of environment entries in ES5:

Declarative environment entries are used to determine the effect of ECMAScript syntax elements, such as FunctionDeclarations, VariableDeclarations, and Catch, which directly associate identifier bindings with ECMAScript language values. An environment recording object is used to determine the impact of ECMAScript elements, such as Program and WithStatement, that associate identifier bindings with the properties of an object.

So, the question is why declarative environment entries were introduced, and not just using object environment entries similar to ES3 variable objects. The difference is that declarative environment entries can have immutable bindings:

In addition to the mutable bindings supported by the entire Recording environment, declarative environmental records also provide immutable bindings. An optional binding is one where the relationship between the identifier and the value cannot be changed after it has been established.

Immutable bindings do not have a direct equivalent in objects. A property can be defined as either non-configurable or non-writable, becoming unchanged. Nonetheless,

Creating and initializing immutable bindings are different steps, so it is possible that such bindings exist either in an initialized or uninitialized state.

But you cannot have an uninitialized property. If you define a non-configurable non-writeable property with an undefined value, you cannot initialize it to the desired value.

I do not think it is possible to have uninitialized immutable bindings in ES5. CreateImmutableBinding is only used in Activating Ad Binding and Function Definition , and in both cases it is immediately initialized using InitializeImmutableBinding.

But perhaps this was done to allow uninitialized immutable bindings as extensions to the language, such as JavaScript 1.5 const . Or perhaps they already had in mind the ES6 const .

+2
source

The same author, whose ES3 related article, also wrote about ES5 (and even related this section there). I will quote Mr. Soshnikov from his "Declarative Entry Record" in ECMA-262-5. Chapter 3.2. Lexical environments: implementation of ECMAScript :

In the general case, declarative record bindings are supposed to be stored directly at a low implementation level (for example, in virtual machine registries, thereby providing quick access). This is the main difference from the old activation object concept used in ES3.

That is, the specification does not require (or even indirectly recommends) to implement declarative records as simple objects, which in this case are inefficient. The consequence of this fact is that declarative environment records are not supposed to be exposed directly to the user level, which means that we cannot access these relationships, for example, record properties. In fact, we could not even earlier, even in ES3, - the activation object was also inaccessible directly to the user (with the exception of the Rhino implementation, which, however, opened it through __parent__ ).

Potentially declarative entries allow you to use full lexical addressing , that is, get direct access to the necessary variables without any search in the chain of chains - regardless of the depth of the nested area (if the storage is fixed and unchanged, all address variables can be known even during compilation) . However, the ES5 specification does not mention this fact directly.

So, once again, the main thing that we must understand why it was necessary to replace the concept of the old activation object with a declarative record of the environment is, first of all, the effectiveness of implementation.

Thus, since Brendan Eih is also mentioned (last paragraph) - the implementation of the activation object in ES3 was just a โ€œmistakeโ€: I note that there are some real improvements in ES5, in particular in Chapter 10, which now uses declarative binding environments. ES1-3 abuses objects for regions (again, I was to blame for this in JS in 1995, saving on objects needed to implement the language in a big hurry) was a mistake, not a function. "

I do not think that I could express it better.

+1
source

Source: https://habr.com/ru/post/1259585/


All Articles