If I declare a variable in a function using var
then a slot for that variable is added to the LexicalEnvironment
defined by that function.
Questions like this are best be answered by looking at the spec:
Block : { StatementList }
- Let oldEnv be the running execution context’s LexicalEnvironment.
- Let blockEnv be NewDeclarativeEnvironment(oldEnv).
- Perform BlockDeclarationInstantiation(StatementList, blockEnv).
- Set the running execution context’s LexicalEnvironment to blockEnv.
- Let blockValue be the result of evaluating StatementList.
- Set the running execution context’s LexicalEnvironment to oldEnv.
- Return blockValue.
NOTE: No matter how control leaves the Block the LexicalEnvironment is always restored to its former state.
So what happens here?
When the block is evaluated, a new lexical environment is created, with the current lexical environment as "parent". The new environment replaces the current environment for the duration of evaluating the block.
If I use a block-scoped declaration, how is the surrounding
LexicalEnvironment
affected?
Other than it is temporarily replaced, it is not affected at all.
function() {
var foo;
}
As you mentioned, foo
is available in the LexicalEnvironment
is global to all inner functions within that function.
But
function() {
{
let foo; // How does this affect the LexicalEnviroinment?
}
}
Here foo
is local to that block alone. It won't be visible outside that block.
How does it affect the LexicalEnvironment
?
If you are referencing, foo
anywhere inside that block, the local let foo
will override the global var foo
which you've defined in that function.
With respect to ES6,
function example(x) {
console.log(y); // ReferenceError: y is not defined
if (x) {
let y = 5;
}
}
Variables declared with a let
statement are created as bindings on the lexical environment, rather than the variable environment, of the current execution context. A change to the specification of block statements in ES6 means that each block has its own lexical environment. In the above example, a new lexical environment is created when the block (the body of the if statement) is evaluated. When the let statement is evaluated a binding is added to this lexical environment and is innaccessible from the outer lexical environment (that of the function declaration itself).
Refer