Understanding JavaScript Closure with example

Co-Founder, @CreoWis | Teacher, @tapaScript | Founder, @ReactPlay | YouTuber | Writer | Human
Search for a command to run...

Co-Founder, @CreoWis | Teacher, @tapaScript | Founder, @ReactPlay | YouTuber | Writer | Human
I was searching for an article about Closures recently. Thank you for writing this! 😊
Thanks Subha for reading this! Hope it was as per your expectations.. Subha Chanda
Subha Chanda yeah I am! You too? Small world..
Not actually! I am doing B. Sc in CS from A. C. College. 😅 Tapas Adhikary
In this series, I'll bring some fundamental concepts from JavaScript to you. It is going to be fun learning for JS Beginners(and for Experienced folks too) to get the foundation right.
Introduction As a beginner to the JavaScript programming language, I had faced this question so many times: Does JavaScript Interprets the Source code, or it really Compiles? Many of the answers that I found on the internet made me as Confused as, ...
Traditional SSR is great, but it has a massive buffering problem. Let's look into the SSR Streaming and learn how it could be a game changer.

Learn how to build maintainable, reusable forms in React using design patterns like custom hooks, compound components, and context for scalable CRUD

Learn how JavaScript variables work, including let vs const, primitive and reference types, pass by value, and how JavaScript stores data in memory.

A beginner-friendly introduction to JavaScript covering what it is, how it works, and how to set up your JavaScript environment

Learn how the promises are handled internally using event loop. This concept is essentials to debug and work with async programming.

GreenRoots Blog - A Blog by Tapas Adhikary
186 posts
Educator | YouTuber | Building ReactPlay | Let's Connect
All's well that ends well.
Welcome to the last post of the series JavaScript: Cracking the Nuts. I want to thank you all for liking the series so far. There is another reason why this article is special to me. This is my 50th 🎉.
If you are new to the series and want to check out previous articles, here are the links,
Let us get started with the understanding of another JavaScript fundamental called Closure.
Closure is considered an advanced concept in JavaScript. It may take a while to understand the concept fully. But, do not worry. As you have come across the fundamentals of Execution Context, Scope and Scope Chain in the previous articles of the series, it is going to be much simpler for you.
Let us start with a simple code example,
function sayHello(msg) {
return function(name) {
console.log(`${name}! ${msg}`);
}
}
Here we have a function sayHello() that takes a message as an argument. In JavaScript, functions can return another function. sayHello() returns a function that takes name as an argument and logs the name and message in the console. The function inside sayHello() is called inner function and sayHello() can be referred as an outer function.
Fair enough. How do we invoke them? Here it is,
var messageFor = sayHello('Hello, there!');
console.log(messageFor('Jack'));
As sayHello() returns a function, the variable messageFor points to a function. In the next line, we invoke messageFor() passing the value 'Jack'. It logs the following output,
Jack! Hello, there!
But, we have a few questions to ask and get clarifications about,
sayHello() gained access to the msg variable? How is that possible?scope here? The msg variable is in no way in the scope of the inner function. Then how is it working?The answer is, it is working with the help of a JavaScript feature called Closure.
By now, we are aware,
global execution context and function execution context. We have seen this picture before,

In JavaScript, a function can be nested inside another function. The nested function is called the inner function. This inner function can access the variables defined in the outer function's context. It is done by closure. So, it is the inner function that creates a closure to the outer function.
Let us understand the execution steps of the example above in more details. Here is the code again,
// declare the function
function sayHello(msg) {
// it returns another function
return function(name) {
console.log(`${name}! ${msg}`);
}
}
// invoke the function that returns a function
var messageFor = sayHello('Hello, there!');
// invoke the returned function
console.log(messageFor('Jack'));
execution phase, the function sayHello() gets invoked.var messageFor = sayHello('Hello, there!');
sayHello() and it gets added to the execution stack. Note, it has an argument called, msg and it will be available in its execution context. function sayHello(msg) {
// code
}
sayHello() returns another function and pop out the execution stack. function sayHello(msg) {
// it returns another function
return function(name) {
console.log(`${name}! ${msg}`);
}
}
But, hold on. sayHello() returns an inner function. It means, the inner function will create a closure to the outer function's(sayHello()) execution context. With that, it will also have all the access to the outer function's variables. In this case, it is msg.messageFor('Jack'). This is nothing but that inner function returned in the last step. console.log(messageFor('Jack'));
This invocation will create a new function execution context. As we pass Jack as an argument, it will be available in its execution context. But remember, it also has access to the msg as explained in the step above.This is how Closure helps retain access to the parent's execution context even when it has already been executed and removed from the execution stack.
This is a compelling concept. I hope it was simpler to understand. Not yet? Alright, let us see all these happening visually,

The inner function creates a special scope called Closure Scope on the outer function's execution context. This is how the closure scope will be(in red border),

With the explanation we have gotten so far, what do you think will be the following?
function myMultiplier(x) {
return function inner(y) {
return x * y;
}
}
and then invoke the functions like,
var multiplyOf5 = myMultiplier(5);
var multiply5x4 = multiplyOf5(4);
console.log(multiply5x4);
I'm sure you got this! Yeah, the inner function will have access to the variable of parent function's(myMultiplier()) execution context. The inner function now has two variables, i,e, x, and y, in scope.
In the execution phase, x and y have values as 5 and 4, respectively. The multiplication of these results in the value, 20. Isn't that simple now?
Closure is much easy to understand when you get to it conceptually with execution context and scope. I hope you will try out many more examples with the understanding we got here.
I hope you find the article useful. Please Like/Share so that it reaches others as well. If you enjoyed this article or found it helpful, let's connect. You can find me on Twitter(@tapasadhikary) sharing thoughts, tips, and code practices.
To get e-mail notifications on my latest posts, please subscribe to my blog by hitting the Subscribe button at the top of the page.
I hope the entire series was useful to you so far and helped in learning some JavaScript concepts under the hood.
See you sooner with another series in the making. Please stay tuned!