🧠 Lexical Scoping and Closures —
Ever seen a function in JavaScript remember a variable even after it's done running?
That’s not magic — it’s Lexical Scoping and Closures.
Let’s break it down with real-world analogies, demos, and how the industry uses it.
🔍 What is Lexical Scoping?
Lexical Scoping means:
"Variables are accessible based on where they are written in the code — not where they are called."
🏠 Analogy:
Imagine your house has rooms.
If you leave your phone in the living room, you can use it there.
But if you go to the kitchen, you can’t use your phone unless you bring it with you.
Same with code — variables live in their scope (room).
Functions can access variables in their room and the rooms outside — but not inside other rooms.
function outer() {
const message = "Hello from outer!";
function inner() {
console.log(message); // ✅ Accessible due to lexical scope
}
inner();
}
outer();
🔐 What is a Closure?
A Closure is when a function “remembers” variables from its outer scope, even after the outer function has finished running.
🍱 Analogy:
Think of a lunchbox.
You pack food (variables) inside it.
Even when you leave the kitchen (outer function ends), the lunchbox (inner function) still has the food.
function createCounter() {
let count = 0;
return function () {
count++;
console.log(count);
};
}
const counter = createCounter();
counter(); // 1
counter(); // 2
Here, count
is remembered by the returned function — that’s a closure!
🏭 Real-World Use Cases
Closures are everywhere in production-grade code:
✅ Authentication
function createAuth(secretKey) {
return function validate(token) {
return token === secretKey;
};
}
const validateUser = createAuth("abc123");
validateUser("abc123"); // true
✅ Caching
function memoize(fn) {
const cache = {};
return function (key) {
if (cache[key]) return cache[key];
const result = fn(key);
cache[key] = result;
return result;
};
}
✅ Event Listeners
function setupButton(id) {
let clicked = 0;
document.getElementById(id).addEventListener("click", function () {
clicked++;
console.log(`Clicked ${clicked} times`);
});
}
✅ React Hooks (Under the hood)
Hooks like useState
and useEffect
rely on closures to maintain state across renders.
🧪 Interview Tip
Closures often appear in:
- System design questions (e.g., rate limiters, memoization)
- Frontend logic (e.g., dynamic UI behavior)
- Backend auth and stateful logic
🧠 Final Thought
Closures = Memory + Scope + Power
They let your functions carry context — like a suitcase packed with variables.
If you master this, you unlock the ability to write modular, secure, and efficient code.
🔗 Bonus Demo Playground
Try this in your browser console or CodeSandbox:
function bankAccount(initialBalance) {
let balance = initialBalance;
return {
deposit(amount) {
balance += amount;
console.log(`Deposited: ${amount}, Balance: ${balance}`);
},
withdraw(amount) {
if (amount > balance) {
console.log("Insufficient funds");
} else {
balance -= amount;
console.log(`Withdrew: ${amount}, Balance: ${balance}`);
}
}
};
}
const myAccount = bankAccount(1000);
myAccount.deposit(500);
myAccount.withdraw(300);
📌 Save this article.
🎯 Use it in interviews and real projects.
---
Top comments (0)