JavaScript Tutorial: Scope & Closures
Block scope, function scope, the var hoisting trap, closures, and why functions remember their birth environment.
Where variables live
Scope determines which variables are visible where. Get it wrong and you get mysterious `undefined` values and bugs that only appear sometimes.
Closures are one of JavaScript's most powerful features — and the source of many 'aha!' moments. Once you understand them, you'll see them everywhere: event handlers, callbacks, React hooks, setTimeout patterns.
What you'll learn in this JavaScript scope & closures tutorial
This interactive JavaScript tutorial has 9 hands-on exercises. Estimated time: 22 minutes.
- Block scope vs function scope — `let` and `const` are **block-scoped** — they only exist inside the `{}` that declared them.
- The classic var loop bug — This is JavaScript's most infamous beginner trap. `var` loops with `setTimeout` give unexpected results:
- Hoisting — var vs let vs function — JavaScript 'hoists' declarations to the top of their scope:
- Closures — functions that remember — A **closure** is a function that remembers the variables from its birth scope — even after that scope is gone.
- Closures with parameters — Closures can capture parameters too — making powerful factory functions:
- Private state with closures — Closures are the classic way to create **private state** — variables that can only be accessed through provided methods:
- Closures in callbacks — Closures appear everywhere callbacks are used — in setTimeout, event handlers, array methods.
- Memoisation with closures — Memoisation caches function results — if the same inputs are seen again, return the cached result instead of recalculati…
- Build a state machine — Final challenge — no starter code.
JavaScript Scope & Closures concepts covered
- Where variables live