I'm studying the ECMAScript spec to find out what the expected behavior of vars
statements inside a block is according to the spec:
function test() {
console.log('before block', bar);
{
console.log('in block before declaration', bar);
var bar = 30;
console.log('in block after declaration', bar);
}
console.log('after block', bar);
}
test();
I know that var
is not block-scoped. But I'm curious about how the spec uses concrete definitions of steps to achieve it.
I've read the semantics of the DeclarationInstantiation
of function and global. They take static semantics VarDeclaredNames
and VarScopedDeclarations
of function body or script to create bindings to the environment record. But I can't find the definition in these static semantics of how to deal with the block statement with the nested StatementList. The spec only defined the production for empty block (without any statement):
Or should Block: { StatementList }
be seen as a StatementList
directly?
But in 14.2 it is defined as a single statement?
I found other semantics include instructions for the production Block { statementList }
, so I expect to see something like:
Block: { StatementList }
1. Return VarDeclaredNames of StatementList.
Here's the example defined instructions of production Block { statementList }
in evaluation operation:
I expect to see something like:
Block: { StatementList } 1. Return VarDeclaredNames of StatementList.
Your expectation is well-founded, but it would be rather boring and arduous to define VarDeclaredNames
for every single syntactic element, doing nothing other than recursing into its descendant element.
So the spec authors decided to only provide an implicit definition for these Syntax-Directed Operations:
Unless explicitly specified otherwise, all chain productions have an implicit definition for every operation that might be applied to that production's left-hand side nonterminal. The implicit definition simply reapplies the same operation with the same parameters, if any, to the chain production's sole right-hand side nonterminal and then returns the result.
See also the example following that paragraph.