Back to Blog
JavaScriptClosuresInterview Prep

JavaScript Closures Interview Guide: Questions, Examples & Pitfalls

May 29, 2026·8 min read

Closures are the single most-tested JavaScript concept in technical interviews. They come up at every level, from entry-level screening calls asking "what is a closure?" to senior-level questions about memory leaks, module patterns, and React hook internals. If you can explain closures clearly and debug closure-related bugs on the spot, you signal a genuine understanding of how JavaScript executes, not just how to use it.

This guide covers what closures are, how they work in the JavaScript engine, the classic pitfalls that trip candidates up, and the specific interview questions you are most likely to face.

1. What Is a Closure?

A closure is formed when a function is defined inside another function and retains access to the outer function's variables, even after the outer function has returned and its execution context has been removed from the call stack.

JavaScript uses lexical scoping: a function's scope is determined by where it is written in the source code, not where it is called. When the inner function is created, it holds a reference to the surrounding scope, this reference is the closure.

javascript
function makeCounter() {
  let count = 0;          // 'count' lives in makeCounter's scope

  return function increment() {
    count++;              // increment closes over 'count'
    return count;
  };
}

const counter = makeCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3
// makeCounter has returned, but 'count' persists via the closure

The increment function keeps the count variable alive because it holds a reference to it. This is the core mechanism: closures prevent the garbage collector from releasing outer scope variables that inner functions still reference.

2. The Classic Loop Closure Pitfall

The most frequently asked closure question in interviews involves a loop with asynchronous callbacks. This pattern trips up a huge proportion of candidates.

javascript
// ❌ Common bug, all callbacks log 3, not 0, 1, 2
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}
// Output: 3, 3, 3

// ✅ Fix 1: use let (creates a new binding per iteration)
for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}
// Output: 0, 1, 2

// ✅ Fix 2: IIFE (works with var, pre-ES6 pattern)
for (var i = 0; i < 3; i++) {
  (function(j) {
    setTimeout(() => console.log(j), 100);
  })(i);
}
// Output: 0, 1, 2
When you use var, there is only one i binding for the entire loop. All callbacks close over the same variable. By the time they run, the loop has finished and i === 3. let creates a new binding per iteration, giving each callback its own copy.

3. Practical Uses of Closures

Interviewers often follow up "what is a closure?" with "where would you use one?" Here are the four patterns that come up most:

  • Data privacy / encapsulation, exposing only a public interface while keeping internal state private (the Module pattern predates ES6 classes).
  • Factory functions, functions that produce customized functions (makeMultiplier, makeAdder).
  • Partial application and currying, pre-filling some arguments to create a specialized version of a function.
  • Memoization, caching expensive computation results in a closed-over Map or object.
javascript
// Data privacy via closure
function createBankAccount(initialBalance) {
  let balance = initialBalance; // private

  return {
    deposit(amount) { balance += amount; },
    withdraw(amount) { balance = Math.max(0, balance - amount); },
    getBalance()    { return balance; },
  };
}

const account = createBankAccount(100);
account.deposit(50);
console.log(account.getBalance()); // 150
console.log(account.balance);      // undefined, not accessible

4. Closures and Memory Leaks

Closures keep outer scope variables alive for as long as the inner function exists. In long-running applications (SPAs, Node.js servers), this can cause memory leaks if you unintentionally hold references to large objects.

Common sources: event listeners that capture large objects and are never removed; closures stored in long-lived arrays; and React effects that close over component state and are not cleaned up.

5. Top Interview Questions on Closures

  • What is a closure? Give an example.
  • What will this loop print? (The classic var/setTimeout pattern.)
  • How is a closure different from a regular function?
  • How do closures enable private variables in JavaScript?
  • Can closures cause memory leaks? How do you prevent them?
  • What is the difference between a closure and a callback?
  • How do React hooks use closures internally?
React hooks are closures. useEffect and useCallback capture variables from their component's render scope, stale closure bugs in React are directly caused by misunderstanding how closures interact with re-renders and dependency arrays.
Enjoyed this guide?

Test what you just learned with a timed JavaScript quiz.