What's Closure in JS?

Search for a command to run...

Thanks Obi
I'm sharing what I've learnt from a course I took: "JavaScript: The Hard Parts v2" from [Frontend Masters](https://frontendmasters.com/courses/javascript-hard-parts-v2/) by Will Sentance.
Hello! Welcome back to my series, JavaScript: The Hard Part cover. If this is my first post in the series you're reading I'll advise you to take a look at the previous articles to follow up with the series. Previous Blogs Principles of Javascript Ex...
With the rise of AI agents, vibe coding, and the advancement of software development tools, it's never been easier to build applications quickly. However, these advancements come at a cost to software

Personal highlights along with Work highlights in 2024

💡 Originally posted here. In the intricate world of web design today, typography serves as a powerful means of expression, improving site usability and it goes beyond the realms of font choice and sizes. In this article we’ll explore a sub-section...

Ever spent hours wrestling with images that refuse to stay put in your web layouts? You're not alone. In this comprehensive guide, we will unravel the mystery behind different image centering methods, from the basic and widely used to the more advanc...

Tailwind CSS recently launched some awesome updates in v3.4, supporting CSS features like Dynamic viewport units, subgrid supports and other features, which we'll go over in this article. It's so easy to be carried away by using the already-known fea...

Hello once again, before I proceed, I'll advise you to go through my previous blog posts in this series, because the previous blog posts will aid you to understand the process of JavaScript Execution before Closure.
But if you're just reading to refresh your memory on the topic Closure, then no need to over the previous articles.
Execution Context and Call stack
I suggest you take a look at this article.
Before I'll get into what Closure is, let's take a look at Scope cause it essential to note before Closure.
Scope is anywhere your variable is being accessed simply, any variable declared outside a function belongs to the Global Scope meanwhile, any variable declared in a function belongs to the Local Scope of that function.
Here is an example to explain what Scope means:
// Global Scope
const a = "Hello"
function func() {
// Function Scope
const a = "hi"
console.log(a, "Function Scope")
}
func()
console.log(a, "Global Scope")
// Output
// "hi" "Function Scope"
// "Hello" "Global Scope"
To make my point clear, I used a constant variable const a which when assigned to a certain value, shouldn't be able to get re-assigned.
But from the example above, there exist a variable const a in the Global Execution Context (Global Scope) and also there exist another variable const a in the Function Execution Context (Local Scope).
Both constant variables have different values because they belong to different scopes.
letvariable also belongs to the Scope which it is declared in, unlike thevarvariable.
Here's a key point you should note:
A Function Scope or Local Scope has access to its parent scope. The parent scope could be either another Local Scope or the Global Scope.
Let's look at this example to buttress my point above:
var first = 1
function func1(num) {
var value = first + num
function func2() {
value = value + num
console.log(value) // 5
}
return func2();
}
func1(2)

🙄 The example looks scary, right? Probably not or otherwise 😉. Allow me to demystify the above instructions.
Note: When a function is invoked it gets added to the Call Stack
first is at the Global Scope having a value, 1func1 is declared in the Global Scopefunc1 is invoked having an argument value 2num with the value passed as the argument (2) which is the func1 parameter.value is being assigned to store the values of variable first + num. Javascript then asks what's first variable, because it doesn't exist in the Function Scope, then it checks the Global Scope, and sees it has the value 1.first (1) plus num (2) gets added and stored in the variable value.func2 and stored in the Local Memory of the func1 function.func2().value is being assigned to value + num values.value and num do not exist in the Local Scope of the func2 function, so Javascript checks the outer scope which is the function func1 scope, gets the values assigned to each variable and perform the arithmetic.Understanding Scope would help understand Closure, if anything isn't clear comment below.
Now that we've gone through Scope, let's look into Closure
If you recall from my previous articles in this series when a function is invoked a Function Execution Context is created and deleted when all instructions have been executed. All variables or instructions stored in the Local Memory of the Function is lost.
But what if there was a way, to let functions remember or hold a certain statement (live data), even though the function has been executed.
That's where Closure comes into play, and it all starts by returning a function by another function.
function createFunction() {
let two = 2
function multiply(num) {
return num * two++
}
return multiply
}
var calc = createFunction()
calc(3) // 6
calc(4) // 12
calc(5) // 20
Let's look a graphical illustration first:

Here is the explanation:
createFunction function is stored in memory (Global Memory)calc is declared and a function invocation is assigned to the variable calcNote: Variable
calcis expected to have a value or function or object returned by thecreateFunctionfunction. In other to get whatsoever that's to be returned fromcreateFunctioninvocation, variablecalcis uninitialised for now until it has a value/function/object.
createFunction() has been invoked in calc variable, a new Function Execution Context.two is stored in the Local memory and assigned the value 2.multiply function and stored in the Local Memory of the createFunction function.multiply: function
Note:
multiplyfunction has closure over variabletwoin thecreateFunctionfunction.
createFunction then returns multiply which is assigned to the calc variable in the Global Scope.Now, calc variable holds a function multiply which is to be passed an argument. For simplicity, I'll illustrate what going on :
var calc = function multiply(num) {
return num * two++
}
It's clear that multiply had closure over the variable two but how?
When a function is defined/ declared in another function it has access/bond to the outer function Local memory.
In this case,
multiplyfunction has a bond to thecreateFunctionfunction Local Memory and any variable declared in it.
Now, that we are aware of this, let's look at what the Backpack is, which is essential to Closure.
The backpack holds the live data (what should be remembered) through a hidden property known as [[scope]] which persists when an inner function is returned out.
From the example above, the backpack holds the variable two since it's been
referenced in the inner Function (multiply).
Note: Any variable declared at the outer function which isn't used by the inner function doesn't have Closure. For example :
function outer() {
let i = 1
function inner() {
return console.log(2)
}
}
var func = outer()
In this case, Closure isn't applicable since there is nothing to remember.
If createFunction function is assigned to a new variable and invoked, that will be a new Scope and also be a new Backpack which doesn't remember what has been run before it.
Let's look at the example :
function createFunction() {
let two = 2
function multiply(num) {
return num * two++
}
return multiply
}
var calc = createFunction()
calc(3) // 6
calc(4) // 12
calc(5) // 20
var calc2 = createFunction()
calc2(3) // 6
calc2(4) // 12
calc2(5) // 20
Wow! A lot we have been through but if you've read so far, thanks, I really appreciate it. But you should know I'm no pro at this concept just sharing how I understand Closure, there are still a lot of Closure offers but this is just the basics, so I'll recommend more articles to read on.
Here are other great articles on this topic:
Thanks for Reading once again, If you find this blog useful please do share and contact me on Twitter @favouritejome1