liveBook · Manning

Execution context

As explained in Secrets of the JavaScript Ninja, Second Edition

An internal JavaScript runtime record that tracks the code being evaluated and the environment used to resolve identifiers.

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

How Secrets of the JavaScript Ninja, Second Edition covers it

How deep it goes
Explains global and per-invocation contexts, stack transitions, lexical-environment relationships, and retained generator contexts without detailing an engine implementation.
Examples
Traces nested function calls, constructor methods accessing private variables, and an iterator resuming after `yield`.
What it assumes
Assumes familiarity with JavaScript function calls while defining execution contexts and distinguishing them from the object accessed through `this`.
What you can do after
Diagnose/debug with it by tracing nested calls, distinguishing a call stack from a closure’s environment, and reasoning about suspended generators.
How it connects
Connects execution contexts to the call stack, lexical environments, closures, identifier resolution, and generators.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Secrets of the JavaScript Ninja, Second Edition. The section links point to the parts of the book it draws on.