What are Javascript Closures?
Closures are a fundamental concept in JavaScript that enables powerful features like data privacy, state persistence, and functional programming. This blog will demystify closures with examples and practical use cases.
When are closures created?
Closures are created when a function (inner function) is defined inside another function (outer function). The inner function has access to the outer function's lexical scope (variables) even after the outer function is executed.
Lexical Scope in Javascript
Lexical scope means a function’s scope is determined by where it is written in the code, not where it is executed. This allows inner functions to access variables from their outer functions even if the outer function has already finished executing.
Usage
Closures are used for creating Private variables and persistent States (Cache, Memoisation etc.).
Closures with Examples
A Simple counter
function Outer() {
let count = 0; // count is a private variable
return function inner() {
count++; // count is updated every time inner is called
return count; // the updated value of count is returned
};
}
let Counter = Outer();
Counter(); // 1 (count starts at 0, incremented to 1)
Counter(); // 2 (incremented again)
Counter(); // 3
Building a cache leveraging closure
function ObjectCache() {
let Obj = {}; // Obj acts as a private cache
return function ObjectUpdate(key, value) {
if (!Obj[key]) {
Obj[key] = value; // Add key-value to cache if not already present
return Obj; // Return updated cache
} else {
return new Error("Duplicate Key"); // Prevent overwriting
}
};
}
let cache = ObjectCache();
cache("a", "b"); // {a: 'b'}
cache("a", "c"); // Error: Duplicate Key
cache("alpha", "romeo"); // {a: 'b', alpha: 'romeo'}
Real World Examples
Event Listeners - Click Counter
function attachListener(element) {
let count = 0;
element.addEventListener('click', () => {
count++;
console.log(`Clicked ${count} times`);
});
}
A Better Counter
const CounterModule = (() => {
let count = 0;
return {
increment: () => ++count,
reset: () => (count = 0),
decrement: () => --count
};
})();
CounterModule.increment(); // 1
CounterModule.increment(); // 2
CounterModule.decrement(); // 1
CounterModule.reset(); // 0
That’s all, folks! I hope you found this short blog on closures helpful. If you enjoyed this, check out more articles on my website, https://nandan.dev/
Feel free to comment, email me at connect@nandan.dev, or connect with me on Twitter, Instagram, or GitHub. Don’t forget to subscribe to my newsletter for regular updates on JavaScript topics!
Subscribe to my newsletter
Read articles from Nandan Kumar directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Nandan Kumar
Nandan Kumar
I am Nandan, And you probably know me as a "Software Engineer who "hacked" an Airline to retrieve his luggage". I am a full-time Software Engineer, Tech Speaker, and mentor. I enjoy talking about Web Development, Machine Learning, Natural language Processing, Machine learning Accelerated Mobile Pages, Progressive Web Apps, Cybersecurity, Chatbots, etc. My claim to fame was when I posted a series of tweets on Twitter about data privacy issues on an airline’s website and the tweet got viral for all the good reasons. The story was covered by all major media portals all around the world including BBC, Saudi Gazette, Times of India, Boing Boing, Lallantop etc. and I have been interviewed by some major radio channels and podcasts. In my free time, I like to indulge myself in activities like Photography, Gardening, Snooker, or Boxing. I am a proud owner of many plants, I sometimes talk to them (mostly pep talks).