简体   繁体   中英

ECMASCRIPT Closures - What is Evaluation block in JavaScript?

https://tc39.es/ecma262/multipage/ecmascript-language-statements-and-declarations.html#sec-block-runtime-semantics-evaluation

14.2.2 Runtime Semantics: Evaluation

Block: { }

  1. Return empty.

Block: { StatementList }

  1. Let oldEnv be the running execution context's LexicalEnvironment.
  2. Let blockEnv be NewDeclarativeEnvironment(oldEnv).
  3. Perform BlockDeclarationInstantiation(StatementList, blockEnv).
  4. Set the running execution context's LexicalEnvironment to blockEnv.
  5. Let blockValue be Completion(Evaluation of StatementList).
  6. Set the running execution context's LexicalEnvironment to oldEnv.
  7. Return? blockValue.

Does this part of the documentation refer to when JavaScript "puts the focus" on a new execution context (eg when you start executing a function)?

The question is because I am learning closures.

That part of the specification describes how blocks are evaluated.

Does this part of the documentation refer to when JavaScript "puts the focus" on a new execution context...

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 , class 1 , or — in a complicated way — function 1,2 ), since lexical declarations are block-scoped in JavaScript (although again, for function declarations, it's complicated). But blocks don't create a new execution context.

The question is because I am learning closures.

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 / function declarations here, not class / function expressions . Since class / function expressions don't create a binding (loosely, a variable) in the scope where they appear, they aren't relevant to this discussion. (Recall that a class / function declaration is when the class / function keyword appears where a statement is expected by the parser; if it appears where an expression is expected, it's a class / function expression . Examples:

   function ex1() { }
// ^^^^^^^^^^^^^^^^^^−−−−−−−−−−−−−−−−−−−−−−−− function declaration

   export default function() { }
//                ^^^^^^^^^^^^^^−−−−−−−−−−−−− function declaration (yes, really; this is the only place where a name isn't required on a function declaration)

   const ex2 = function() { };
//             ^^^^^^^^^^^^^^−−−−−−−−−−−−−−−− function expression

   const ex2 = function name() { };
//             ^^^^^^^^^^^^^^^^^^^−−−−−−−−−−− function expression

   someArray.forEach((e) => console.log(e));
//                   ^^^^^^^^^^^^^^^^^^^^^−−− function expression

   class Ex4 { }
// ^^^^^^^^^^^^^−−−−−−−−−−−−−−−−−−−−−−−−−−−−− class declaration

   export default class { }
//                ^^^^^^^^^−−−−−−−−−−−−−−−−−− class declaration (yes, really)

   const Ex5 = class { };
//             ^^^^^^^^^−−−−−−−−−−−−−−−−−−−−− class expression

   const Ex6 = class Name { };
//             ^^^^^^^^^^^^^^−−−−−−−−−−−−−−−− class expression

   const Ex7 = register(class { });
//                      ^^^^^^^^^−−−−−−−−−−−− class expression

2 Re the complicated relationship function declarations have with blocks: Originally, function declarations created var -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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM