Learn Computer Academy

Scope & Closure Visualizer

See the scope chain build up and tear down as real code runs — every variable’s real value, the real ReferenceError a temporal dead zone throws, and exactly what a closure keeps alive after its outer function has already returned.

Browse JavaScript lessons

There’s no JS API that exposes a scope chain the way Error().stack exposes a call stack, so this tool is presets only, not free-form code — the scope structure shown (which box holds which variables) is hand-authored to match each preset exactly. Everything inside the boxes is real, though: every value, every console line, and every ReferenceError message is captured live from the preset’s code actually running in a sandboxed iframe.

Code

Example
snapshot(['global'], {});
if (true) {
  var x = 1;
  let y = 2;
  console.log('inside the block, x =', x, 'y =', y);
  snapshot(['global', 'if-block'], { x: x, y: y });
}
console.log('outside the block, x =', x);
console.log('y does not exist out here — it only ever lived inside the if-block');
snapshot(['global'], { x: x });

How this works

Scope and hoisting are properties of the source code itself, not of a running engine — there’s no runtime API that lists a scope chain the way there’s one for reading a call stack, so this tool can’t auto-derive it from arbitrary code the way the Event Loop and Recursion visualizers derive theirs. Each preset’s scope boxes are hand-matched to its actual code. What stays completely real: every variable value shown, every console line, and the exact ReferenceError JavaScript throws for accessing a let/const before its declaration (the "temporal dead zone") are all captured live via a small snapshot() helper placed at meaningful points in the preset’s own real code, running for real in a sandboxed iframe — not invented text standing in for what the engine would actually do.