14.2.2 Runtime Semantics: Evaluation
Block : { }
- Return empty.
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 Completion(Evaluation of StatementList).
- Set the running execution context's LexicalEnvironment to oldEnv.
- Return ? blockValue.
Does this part of the documentation refer to when JavaScript "puts the focus" on a new execution context (e.g. when you start executing a function)?
The question is because I am learning closures.
That part of the specification describes how blocks are evaluated.
Not quite. A block with statements in it creates a new declarative lexical environment (Step 2), not a new execution context; it does then set this new environment record as the running execution context's LexicalEnvironment (Step 4). The declarative lexical environment for the block is there to contain any lexical declarations inside the block (that is, declarations using
let,const,class1, or — in a complicated way —function1,2), since lexical declarations are block-scoped in JavaScript (although again, forfunctiondeclarations, it's complicated). But blocks don't create a new execution context.There's a bit of a relationship between this and closures, in that a closure closes over the current environment record where it's created. So if you're wondering if a closure created within the block closes over the bindings within the block: Yes, it does.
1 Note we're talking about
class/functiondeclarations here, notclass/functionexpressions. Sinceclass/functionexpressions don't create a binding (loosely, a variable) in the scope where they appear, they aren't relevant to this discussion. (Recall that aclass/functiondeclaration is when theclass/functionkeyword appears where a statement is expected by the parser; if it appears where an expression is expected, it's aclass/functionexpression. Examples:2 Re the complicated relationship
functiondeclarations have with blocks: Originally,functiondeclarations createdvar-style function-scoped globals, and declaring functions in blocks didn't have specified behavior (it was an allowed extension to the spec, and they were done differently by different JavaScript engines [or even the same engine between versions]). Recent versions of the specification have codified the ways in which major implementations overlapped with regard to function declarations in blocks, which includes some block-level semantics. I go into the gory details in Chapter 3 of JavaScript: The New Toys, but really, in general, just avoid function declarations in blocks (use an expression instead); not all situations have specified behavior, and the behavior that is specified may be surprising.