Closures are one of the most frequently tested topics in JavaScript interviews because they reveal how deeply you understand scope, memory management, and data privacy. In this article, weโll go through 10 well-structured interview questions, each designed to test your practical understanding of closures โ from simple function scope to encapsulating private data.
1. (Interview Question 1) What is a closure in JavaScript?
Focus: Understanding closure fundamentals
Model Answer:
A closure is a function that remembers and accesses variables from its outer scope, even after that outer function has finished executing. Closures are created whenever a function is defined inside another function and the inner function references variables from the outer one.
function outer() {
let count = 0;
return function inner() {
count++;
console.log(count);
};
}
const counter = outer();
counter(); // 1
counter(); // 2
Here, the inner function โremembersโ count even after outer() has returned.
Possible Follow-up Questions: ๐ (Want to test your skills? Try a Mock Interview โ each question comes with real-time voice insights)
- Can closures access variables from multiple outer scopes?
- How does garbage collection handle variables captured by closures?
- Whatโs the difference between a closure and a regular function scope?
2. (Interview Question 2) How can closures be used to implement data privacy?
Focus: Encapsulation and private state
Model Answer:
Closures can hide variables inside a functionโs scope so theyโre not accessible from the outside. This mimics private variables, a pattern often used before ES6 class fields.
function createBankAccount(initialBalance) {
let balance = initialBalance;
return {
deposit(amount) { balance += amount; },
withdraw(amount) { balance -= amount; },
getBalance() { return balance; }
};
}
Here, balance is private and cannot be modified directly.
Possible Follow-up Questions: ๐ (Want to test your skills? Try a Mock Interview โ each question comes with real-time voice insights)
- How would you modify this example using ES6 private fields (
#balance)? - What are the pros and cons of using closures for data privacy?
- Could this approach lead to memory leaks? Why or why not?
3. (Interview Question 3) What will this code output and why?
Focus: Loop variable capture in closures
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
Model Answer:
It will print 3, 3, 3 because var has function scope, not block scope. By the time the callback executes, the loop has already completed and i equals 3.
To fix it:
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
Now it prints 0, 1, 2 because let creates a new block-scoped variable on each iteration.
Possible Follow-up Questions: ๐ (Want to test your skills? Try a Mock Interview โ each question comes with real-time voice insights)
- How could you fix this without using
let? - What happens if you wrap
setTimeoutin an IIFE? - Why do closures behave differently with
varandlet?
4. (Interview Question 4) Explain how closures enable function factories.
Focus: Functional programming pattern
Model Answer:
Closures allow a function to โrememberโ parameters and create specialized versions of other functions.
function multiplier(factor) {
return function (num) {
return num * factor;
};
}
const double = multiplier(2);
const triple = multiplier(3);
double(5) โ 10, triple(5) โ 15.
Here, each function retains its own closure with factor.
Possible Follow-up Questions: ๐ (Want to test your skills? Try a Mock Interview โ each question comes with real-time voice insights)
- What are real-world use cases for this pattern?
- How do closures help with partial application or currying?
- Could this lead to performance overhead in large applications?
5. (Interview Question 5) How do closures interact with asynchronous code?
Focus: Event loop and closure persistence
Model Answer:
Closures retain variables even when the surrounding function has finished, which is crucial for async operations like setTimeout or fetch.
function delayedLog(message, delay) {
setTimeout(() => console.log(message), delay);
}
delayedLog("Hello", 1000);
Here, the closure retains access to message until the timeout executes.
Possible Follow-up Questions: ๐ (Want to test your skills? Try a Mock Interview โ each question comes with real-time voice insights)
- How does JavaScriptโs event loop handle closures in async operations?
- Can closures cause unexpected memory retention in async callbacks?
- How would you debug closure-related async bugs?
6. (Interview Question 6) How can closures help with memoization?
Focus: Optimization using closure-based caching
Model Answer:
Closures can store computed results to avoid redundant work.
function memoizedAdd() {
const cache = {};
return function (x, y) {
const key = `${x},${y}`;
if (cache[key]) return cache[key];
return (cache[key] = x + y);
};
}
Here, the closure keeps the cache alive between calls, optimizing performance.
Possible Follow-up Questions: ๐ (Want to test your skills? Try a Mock Interview โ each question comes with real-time voice insights)
- What are potential drawbacks of using closures for caching?
- How would you implement cache eviction?
- How could you generalize this for any pure function?
7. (Interview Question 7) What happens if a closure references a variable that changes later?
Focus: Reference vs. value in closures
Model Answer:
Closures capture references to variables, not their values at the moment of creation.
let counter = 0;
function makeLogger() {
return function () {
console.log(counter);
};
}
const log = makeLogger();
counter = 5;
log(); // 5
Because counter is captured by reference, its updated value is logged.
Possible Follow-up Questions: ๐ (Want to test your skills? Try a Mock Interview โ each question comes with real-time voice insights)
- How can you capture the value at creation instead of a reference?
- What happens if the variable is an object?
- Can closures capture constants differently?
8. (Interview Question 8) Can closures cause memory leaks?
Focus: Memory management and lifecycle
Model Answer:
Yes, if closures unintentionally retain references to large or unused objects, the garbage collector wonโt reclaim them.
Example:
function createLeak() {
const bigData = new Array(1000000).fill('*');
return function () {
console.log(bigData.length);
};
}
As long as the returned function exists, bigData remains in memory.
Possible Follow-up Questions: ๐ (Want to test your skills? Try a Mock Interview โ each question comes with real-time voice insights)
- How can you prevent memory leaks caused by closures?
- When does garbage collection reclaim closed-over variables?
- How do weak references relate to this issue?
9. (Interview Question 9) Whatโs the difference between closures and immediately invoked functions (IIFEs)?
Focus: Scoping and encapsulation comparison
Model Answer:
An IIFE runs immediately to create a private scope, while a closure persists to maintain access to variables after execution.
(function() {
let privateData = 42;
console.log(privateData);
})(); // Executes once
function makeClosure() {
let privateData = 42;
return () => console.log(privateData);
}
const fn = makeClosure();
fn(); // Retains access
Closures preserve state, IIFEs isolate execution.
Possible Follow-up Questions: ๐ (Want to test your skills? Try a Mock Interview โ each question comes with real-time voice insights)
- Can IIFEs return closures?
- How did IIFEs influence early JavaScript module design?
- How do ES modules make IIFEs less necessary today?
10. (Interview Question 10) How do closures enable modular design in JavaScript?
Focus: Module pattern and architecture
Model Answer:
Closures are the foundation of the module pattern, allowing functions to expose public APIs while keeping implementation details private.
const CounterModule = (function() {
let count = 0;
function increment() { count++; }
function getCount() { return count; }
return { increment, getCount };
})();
count is private; only increment and getCount are exposed.
Possible Follow-up Questions: ๐ (Want to test your skills? Try a Mock Interview โ each question comes with real-time voice insights)
- How does this compare with ES6 modules?
- What happens if multiple modules share the same closure?
- Can closures simulate class inheritance patterns?
Top comments (0)