Skip to content
masterclassBuddyTech Buzz5 fresh blogs · 5:00 AM IST

JS Puzzles · Const

Closures

Closures let functions retain access to variables from the lexical environment where they were created. This supports persistent state, private data, and callbacks that run after their surrounding function has finished.

How it works

A closure is a function together with the lexical environment where it was created. JavaScript functions retain a reference to that environment, allowing them to read or change outer variables later; variable lookup proceeds from the current environment outward through the scope chain.

Syntax

function outer() { const value = ...; return function inner() { ...value... }; }

Key points

  • Functions, blocks, and scripts each have an associated lexical environment that stores bindings and links to an outer environment.
  • A lexical environment contains an environment record for local bindings plus a reference to its outer lexical environment.
  • Calling a function creates a fresh environment for that invocation’s parameters and local variables.
  • JavaScript functions are closures by default, although many do not visibly capture useful outer state.
  • A closure allows code in a function to access variables from enclosing scopes.
  • Variable resolution follows the scope chain from the current environment toward the global environment.

Common mistakes

  • A function remembers the environment from its creation site, not the location where it is eventually called.
  • Name lookup checks the nearest environment first, so an inner declaration can shadow an outer variable.

Example: A private counter

function makeCounter() {
  let count = 0;
  return () => ++count;
}

const counter = makeCounter();
console.log(counter()); // 1
console.log(counter()); // 2

The returned function keeps access to count after makeCounter has finished, so each call updates the same private variable.

When to use it

Encapsulation

Keep mutable state private behind a returned function.

Callbacks

Preserve context for callbacks executed later.

Function factories

Build configurable functions by capturing setup values.

Interview questions

QWhat is a closure?

A closure combines a function with the lexical environment in which that function was created. The function can later access variables from that environment even after the surrounding call has returned.

Follow-up: What determines which variable is read when several scopes use the same name? Lookup starts in the innermost environment and continues outward, so the nearest binding wins.

QHow can a closure preserve private state?

Each function call creates a new lexical environment for its parameters and local variables. A returned inner function retains the relevant environment, which lets separate calls maintain separate captured state.

Follow-up: Why do two counters made by the same factory not share state? Each factory call creates a distinct environment, and each returned function closes over its own environment.

QWhy can closures in loops produce unexpected values?

let and const create block-level bindings, while var is scoped to the current function or script. In a loop, block-scoped bindings can give iterations distinct captured values; var commonly leaves callbacks sharing one binding.

Follow-up: How can the var loop issue be avoided? Use let for the loop variable or create a separate scope for each iteration.

  • Lexical Environment
  • Environment Record
  • outer lexical environment
  • let
  • const
  • var

Source: Variable scope, closure - The Modern JavaScript Tutorial. Checked 2026-10-15.