JavaScript Runtime6h estimated

Execution Context & Hoisting

Difficulty
Importance

The problem

Before a single line of JavaScript runs, the engine needs to know what variables and functions exist in the current scope — without a setup phase, forward references (calling a function defined later in the file) would be impossible and scoping rules would be unpredictable.

Why now

Functions and scope already established what scope is, but treated it as if bindings simply appear the instant a line executes. JavaScript's actual behavior is more specific: it scans a scope for declarations before running any code in it, which is why some patterns work that a naive line-by-line model wouldn't predict.

Mental model

Before executing a function or script, the engine does a quick pass to register every var and function declaration in that scope — that pre-pass is 'hoisting.' Function declarations are hoisted with their full body attached (callable before their line); var is hoisted but left undefined until its assignment line actually runs; let and const are hoisted too, but sit in an inaccessible 'temporal dead zone' until their own line executes.

Requires

Unlocks

Used in

Projects

  • Write code that calls a function before its declaration (works) and one that reads a const before its declaration (throws), and explain the difference in terms of hoisting
  • Predict, then verify, the output of a small quiz mixing var, let, and function declarations accessed before their line

Examples

  • greet(); function greet() { console.log('hi'); } works because function declarations hoist with their full body
  • console.log(x); let x = 5; throws a ReferenceError — x is hoisted but stuck in the temporal dead zone until its line runs

Resources

Mastery checklist