When one function calls another, how does JavaScript know where to return? It tracks execution with execution contexts. One global execution context is created when a program starts; each function invocation creates a new function execution context. An execution context is an internal runtime mechanism, not the object accessed through `this`. section 5.3
Following an ordinary function call:
- The current context waits while the called function’s context is pushed onto the execution context stack, also called the call stack. section 5.3
- When the function finishes, its context is usually discarded and the caller’s context resumes. The stack keeps those return positions in order. section 5.3
Listing 5.5. The creation of execution contexts
function skulk(ninja) { #A
report(ninja + " skulking"); #A
} #A
function report(message) { #B
console.log(message); #B
} #B
skulk("Kuma"); #C
skulk("Yoshi"); #C
Trace either `skulk` call: execution begins in the global context, enters `skulk`, then enters `report`. As each function finishes, execution returns to its caller. The second `skulk` call creates a new function execution context rather than reusing the first. section 5.3
Execution contexts also help explain closures when considered alongside lexical environments. A constructor invocation creates an environment for its local variables. Functions created there retain a reference to that environment, so methods can later access a variable such as `feints` even though outside code cannot access it directly. Each constructed object gets methods closing over its own constructor environment. section 5.6 section 5.6.1
Generators are the interesting exception to the usual finish-and-discard story. Calling a generator returns an iterator without running its body. Calling the iterator’s `next()` activates the generator’s context; reaching `yield` removes that context from the stack but preserves it so a later `next()` can resume execution where it stopped. section 6.2.4 section 6.2
