First of all, you should know that all these terms simply describe concepts. They do not dictate any implementation. But, since it can be difficult to imagine / visualize, it can be useful to think of these concepts as how you know, for example, maps or tables.
Declarative Environment Records (DER) and Object Environment Records (OER) have one thing in common: they are environment (ER) records that are defined in the as specification :
Identifier bindings created within the scope of the associated Lexical environment are recorded in the environment record.
This basically means that ER keeps track of variable names and function names and their associated values.
Consider the following example:
var foo = 42; function bar() { };
The corresponding ER will have two entries, one for foo and one for bar . If you imagine that ER is a table, then it will look like
name value ---------------------- foo 42 bar <function object>
Now about the differences between DER and OER. DER may be the easiest to understand.
Declarative Environment Record
The declarative term should sound familiar, as we often talk about variable declarations and function declarations. The specification states:
Each declarative environment entry is associated with an area of ββthe ECMAScript program that contains declarations of variables and / or functions. A declarative environment record associates a set of identifiers defined by declarations contained in its scope.
So when you see
var foo = 42;
or
function bar() { }
then you can assume that their names and values ββare stored in DER.
Object Environment Record
OERs are less common, but at least one OER exists in every JS application. The specification describes it as
Each object environment record is associated with an object called its binding object. An object environment record associates a set of identifier names that directly correspond to the property names of the binding object.
Have you ever wondered why the properties of the window object are global variables? This is because the global scope ER is OER: window is a binding object, and a corresponding record is created in OER for each of its properties. This is also indicated in the specification:
Global environment An environment record is an object environment record whose binding object is a global object.
Here is an example: Let's assume that the binding object
var obj = { answer: 42 };
then oer will be
name value ------------------------ answer 42
Note that in this case, the binding object ( obj ) is actually a JavaScript object. You are in the same situation when using the with statement:
var obj = { foo: 42; }; with (obj) { foo = foo / 2; } console.log(obj);
with creates OER and populates it with the names and values ββof the properties from the passed object. This is why you can access them without explicitly accessing them through obj.* . OER will also necessarily update the binding object with a new value if one of them is assigned to one of the identifiers.
Activation object
This is similar to ES3, activation objects (AO), which are automatically created when the function is executed and contain a link to a special arguments object. This seems to be related to DER, but should still be something independent.
Apparently, the concept of ES does not exist in ES5, and I assume that it is not needed, since arguments can be added directly to the DER execution context.
Execution context
A new execution context (EC) is set up whenever the function is executed and used to track the execution status:
The execution context contains any state necessary to track the execution of the code associated with it.
This means that the engine can add any information needed to track progress. But the specification also defines the components that the EC should have, one of which is VariableEnvironment, which is ER (probably always DER, but I don't know for sure). This means that ER is part of the EU.