I have been trying to understand how javascript works under the hood as deep as possible and have been trying to learn the spec simultaneously. I am a bit confused at the description of ForLoopEvaluation
According to the spec:
ForStatement : for ( LexicalDeclaration Expressionopt; Expressionopt ) Statement
Let oldEnv be the
running execution context's
LexicalEnvironment.Let loopEnv be NewDeclarativeEnvironment(oldEnv).
Let isConst be IsConstantDeclaration of LexicalDeclaration.
Let boundNames be the BoundNames of LexicalDeclaration.
For each element dn of boundNames, do
a. If isConst is true, then i. Perform ! loopEnv.CreateImmutableBinding(dn, true).
b. Else, i. Perform ! loopEnv.CreateMutableBinding(dn, false).
Set the running execution context's LexicalEnvironment to loopEnv.
Let forDcl be Completion(Evaluation of LexicalDeclaration).
If forDcl is an abrupt completion, then
a. Set the running execution context's LexicalEnvironment to oldEnv.
b. Return ? forDcl.
If isConst is false, let perIterationLets be boundNames; otherwise let perIterationLets be a new empty List.
If the first Expression is present, let test be the first Expression; otherwise, let test be empty.
If the second Expression is present, let increment be the second Expression; otherwise, let increment be empty.
Let bodyResult be Completion(ForBodyEvaluation(test, increment, Statement, perIterationLets, labelSet)).
Set the running execution context's LexicalEnvironment to oldEnv.
Return ? bodyResult.
Now if we take a look at the ForBodyEvaluation
14.7.4.3 ForBodyEvaluation ( test, increment, stmt, perIterationBindings, labelSet )
The abstract operation ForBodyEvaluation takes arguments test (an Expression Parse Node or empty), increment (an Expression Parse Node or empty), stmt (a Statement Parse Node), perIterationBindings (a List of Strings), and labelSet (a List of Strings) and returns either a normal completion containing an ECMAScript language value or an abrupt completion. It performs the following steps when called:
Let V be undefined.
Perform ? CreatePerIterationEnvironment(perIterationBindings).
Repeat,
a. If test is not empty, then
- Let testRef be ? Evaluation of test.
- Let testValue be ? GetValue(testRef).
- If ToBoolean(testValue) is false, return V.
b. Let result be Completion(Evaluation of stmt).
c. If LoopContinues(result, labelSet) is false, return ? UpdateEmpty(result, V).
d. If result.[[Value]] is not empty, set V to result.[[Value]].
e. Perform ? CreatePerIterationEnvironment(perIterationBindings).
f. If increment is not empty, then i. Let incRef be ? Evaluation of increment. ii. Perform ? GetValue(incRef).
Now when we look at CreatePerIterationEnvironment, it has this to say:
14.7.4.4 CreatePerIterationEnvironment ( perIterationBindings )
The abstract operation CreatePerIterationEnvironment takes argument perIterationBindings (a List of Strings) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:
If perIterationBindings has any elements, then
a. Let lastIterationEnv be the running execution context's LexicalEnvironment.
b. Let outer be lastIterationEnv.[[OuterEnv]].
c. Assert: outer is not null.
d. Let thisIterationEnv be NewDeclarativeEnvironment(outer).
e. For each element bn of perIterationBindings, do
- Perform ! thisIterationEnv.CreateMutableBinding(bn, false).
- Let lastValue be ? lastIterationEnv.GetBindingValue(bn, true).
- Perform ! thisIterationEnv.InitializeBinding(bn, lastValue).
f. Set the running execution context's LexicalEnvironment to thisIterationEnv.
Return unused.
I do not understand when a for loop is executed, since no function is being called a new execution context is not created. Why is it saying here for a normal for loop that if there are any perIterationBindings, that the lastIterationEnvironment should be the running execution context's LexicalEnvironnment?
I could be wrong but is this due to a possible use of the comma operator whereby a getter function is used? This is the only explanation I can come up with that would warrant the use of the term execution context being used in the context of a traditional for loop.