Ben Aston Ben Aston - 5 months ago 19
Javascript Question

Were variables declared in the initialiser expression of for loops always lexically inside the body

When

let
is used in the initialiser expression of a traditional
for
loop, it is scoped to the block of the for loop.

The spec says:


let
and
const
declarations define variables that are scoped to the
running execution context's
LexicalEnvironment
.


Does that mean that the point of declaration of
i
is (and even in ES5 was(?)) lexically (semantically I know using
var
it would be hoisted) inside the block comprising the body of the
for
loop (because naively it looks like it is outside it).

Or does it mean that this is a new feature of
let
and/or the
for
loop to give it the semantics of being lexically inside the loop body?

To be clear: I know that the visibility semantics are new (i.e. block scoping for
let
vs function scooping for
var
). I am interested in whether the lexical position of definition has always been taken to be inside the body of the loop.

for(let i = 0; i < 10; i++) {
// the body of the loop....
}

Answer Source

Actually, think of it like an imaginary wrapper block with all the for-declared variables aliased within it. Kind of like this:

// Original
for (let i = 0; i < 10; i++) { ... }

// Equivalent
{
    let _i;
    for (_i = 0; _i < 10; _i++) {
        let i = _i;
        ...
        _i = i;
    }
}

It works by creating a new scope within the for to alias the variables, and then effectively updating the aliases at the end of each block.

(Of course, engines implement it differently than this, but that's when you get into compiler theory and the difference between observable semantics and actual implementation.)