Introductions
A closure is created when a function remembers and can access variables from its outer scope, even after the outer function has finished running. Closures are an important JavaScript concept and are commonly used for private data, counters, function factories, and maintaining state. The examples below start with simple closures and gradually move toward practical use cases. JavaScript Closures practice questions with solutions help to understand the concepts.
Question 1: Create a Simple Closure
Problem
Create an outer function with a variable and return an inner function that can access that variable.
Solution
function outerFunction() {
let message = "Hello JavaScript";
function innerFunction() {
console.log(message);
}
return innerFunction;
}
const result = outerFunction();
result();
Output
Hello JavaScript
Step-by-step Explanation
outerFunction()creates a variable calledmessage.innerFunction()is created insideouterFunction().- The inner function can access
message. outerFunction()returnsinnerFunction.- The returned function is stored in
result. result()runs the inner function.- The inner function still remembers
message.
This ability to remember variables from an outer scope is called a closure.
Question 2: Create a Counter Using a Closure
Problem
Create a function that returns another function. Each time the returned function is called, increase a counter by 1.
Solution
function createCounter() {
let count = 0;
return function() {
count++;
console.log(count);
};
}
const counter = createCounter();
counter();
counter();
counter();
Output
1
2
3
Step-by-step Explanation
createCounter()createscountwith a value of0.- The inner function has access to
count. createCounter()returns the inner function.counterstores that returned function.- The first call changes
countfrom0to1. - The second call changes it to
2. - The third call changes it to
3. - The value is remembered between function calls.
Question 3: Create a Private Variable
Problem
Create a function where the balance variable cannot be accessed directly from outside, but can be changed through a returned function.
Solution
function createAccount() {
let balance = 1000;
return function() {
balance += 500;
console.log("Balance:", balance);
};
}
const account = createAccount();
account();
account();
Output
Balance: 1500
Balance: 2000
Step-by-step Explanation
balanceis created insidecreateAccount().- It is not directly available outside the function.
- The returned function can access
balance. - Each time
account()is called,500is added. - The closure remembers the current balance.
- This creates a simple example of maintaining private data.
Question 4: Create a Greeting Function Factory
Problem
Create a function called createGreeting() that accepts a name and returns a function that displays a greeting for that name.
Solution
function createGreeting(name) {
return function() {
console.log("Hello, " + name);
};
}
const greetRahul = createGreeting("Rahul");
const greetPriya = createGreeting("Priya");
greetRahul();
greetPriya();
Output
Hello, Rahul
Hello, Priya
Step-by-step Explanation
createGreeting()receives a name.- The inner function uses that name.
createGreeting("Rahul")creates a function remembering"Rahul".createGreeting("Priya")creates another function remembering"Priya".- Each function remembers its own value.
- This is an example of a function factory using closures.
Question 5: Create a Counter with Increment and Decrement
Problem
Create a counter that provides separate functions for increasing and decreasing a private count.
Solution
function createCounter() {
let count = 0;
return {
increment: function() {
count++;
console.log("Count:", count);
},
decrement: function() {
count--;
console.log("Count:", count);
}
};
}
const counter = createCounter();
counter.increment();
counter.increment();
counter.decrement();
Output
Count: 1
Count: 2
Count: 1
Step-by-step Explanation
countis created insidecreateCounter().- The returned object contains two functions.
- Both functions can access
count. increment()increases the value.decrement()decreases the value.- The
countvariable remains private. - Both functions share the same closure.
Question 6: Create a Discount Calculator with Closure
Problem
Create a function that accepts a discount percentage and returns another function that calculates the discounted price.
Solution
function createDiscount(discount) {
return function(price) {
return price - (price * discount / 100);
};
}
const tenPercentOff = createDiscount(10);
console.log(tenPercentOff(1000));
console.log(tenPercentOff(500));
Output
900
450
Step-by-step Explanation
createDiscount()receives the discount percentage.- The inner function receives a product price.
- The inner function remembers the discount value.
tenPercentOffremembers a10%discount.- For
1000, the discount is100. - The final price is
900. - For
500, the discount is50. - The final price is
450.
Question 7: Create a Private User Name
Problem
Create a function that stores a user’s name privately and provides a function to display it.
Solution
function createUser(name) {
return {
getName: function() {
return name;
}
};
}
const user = createUser("Aman");
console.log(user.getName());
Output
Aman
Step-by-step Explanation
nameexists insidecreateUser().- The returned object contains
getName(). getName()can access the outernamevariable.- The outside code cannot directly access the local
namevariable. - The function provides controlled access to the value.
This is one practical use of closures for creating private data.
Question 8: Create Multiple Independent Counters
Problem
Create two counters using the same function. Make sure each counter maintains its own value.
Solution
function createCounter() {
let count = 0;
return function() {
count++;
console.log(count);
};
}
const counter1 = createCounter();
const counter2 = createCounter();
counter1();
counter1();
counter2();
counter1();
counter2();
Output
1
2
1
3
2
Step-by-step Explanation
counter1 and counter2 are created by separate calls to createCounter().
The first counter has its own count:
counter1 → 1 → 2 → 3
The second counter has its own count:
counter2 → 1 → 2
They do not share the same variable.
This happens because every call to createCounter() creates a separate closure.
Question 9: Use a Closure with setTimeout()
Problem
Create a function that remembers a message and displays it after a short delay.
Solution
function showMessage(message) {
setTimeout(function() {
console.log(message);
}, 1000);
}
showMessage("Hello after one second");
Output
After approximately one second:
Hello after one second
Step-by-step Explanation
showMessage()receives amessage.setTimeout()receives an inner function.- The inner function uses the
messagevariable. - JavaScript schedules the callback to run later.
- Even after
showMessage()finishes, the callback remembersmessage. - After approximately one second, the message is displayed.
This is a practical example of closures in asynchronous JavaScript.
Question 10: Create a Secure PIN Checker
Problem
Create a function that stores a PIN privately and returns another function that checks whether a supplied PIN is correct.
Solution
function createPinChecker(correctPin) {
return function(pin) {
if (pin === correctPin) {
return "PIN is correct";
}
return "Incorrect PIN";
};
}
const checkPin = createPinChecker(1234);
console.log(checkPin(1234));
console.log(checkPin(1111));
Output
PIN is correct
Incorrect PIN
Step-by-step Explanation
createPinChecker()receives the correct PIN.- The PIN is stored inside the outer function.
- The returned function can access the PIN.
checkPin(1234)compares the supplied PIN with the remembered PIN.- The first PIN matches.
checkPin(1111)does not match.- The original PIN is not directly exposed outside the closure.
This demonstrates how closures can help maintain private state.
Key Takeaways
- A closure allows an inner function to remember variables from its outer scope.
- Closures are created when functions are defined inside other functions and retain access to the outer variables.
- Closures can maintain state between function calls.
- Counters are a common example of closures.
- Closures can be used to create private variables.
- Function factories often use closures.
- Different closures can maintain separate copies of data.
- Closures are useful with asynchronous functions such as
setTimeout(). - Closures are an important concept behind many JavaScript patterns.
- Understanding closures makes advanced JavaScript easier to learn.
FAQs
1. What is a closure in JavaScript?
A closure is a function that remembers variables from its surrounding lexical scope, even when the outer function has finished executing.
Example:
function outer() {
let message = "Hello";
return function() {
console.log(message);
};
}
const result = outer();
result();
2. Why are closures useful?
Closures are useful for:
- Maintaining state
- Creating private data
- Creating function factories
- Callbacks
- Timers
- Event handlers
- Creating reusable functions
3. Can a closure remember a variable after a function finishes?
Yes. This is one of the main features of closures.
function createCounter() {
let count = 0;
return function() {
count++;
return count;
};
}
The returned function continues to access count.
4. Are closures only used for counters?
No. Counters are just an easy way to understand them. Closures can also be used for private data, configuration functions, callbacks, timers, and many other JavaScript patterns.
5. Can two closures have separate values?
Yes.
const counter1 = createCounter();
const counter2 = createCounter();
Each call creates a separate closure with its own state.
6. Can closures be used with asynchronous JavaScript?
Yes. Closures are commonly used with callbacks such as setTimeout().
function greet(name) {
setTimeout(function() {
console.log("Hello " + name);
}, 1000);
}
greet("Rahul");
The callback remembers the name variable.
7. What is a private variable using a closure?
A private variable is a variable that cannot be directly accessed from outside the function that created it, but an inner function can still access it.
function createUser() {
let name = "Rahul";
return function() {
return name;
};
}
Here, name is protected inside the closure.
Written by Shubhranshu Shekhar, who has trained 20000+ students in coding.
