Photo by Josiah Weiss on Unsplash
Understand JavaScript closures.
Learn what is closures and how closures work behind the scenes.
I have had a lot of difficulties while understanding one of the most interview-asked concepts closures. Most of the time I feel now I know closures then again found something new about it. So in this blog, I will write my way of understanding the closures.
According to MDN docs
A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment).
Before we start
Before diving, into the main parts, let's break down some basic JavaScript.
- Scope
- Lexical Scope
Scope
In JavaScript, scope tells us what variable we have access to.
- Local Scope
- Global Scope
Local Scope
A variable that is inside a specific part of the code is known as inside a local scope. The local scope has further two types:
- Block Scope
- Function Scope
Block Scope
For now, you can think block scope is anything that contains variables inside of the curly braces. e.g.
{
let name = "monu" // inside block scope
let age = "21"
}
note: we can't use a variable declared inside of block scope until its var.
Function Scope
Any variable which is inside of the function is known as inside the function scope. e.g.
function name(){
let name = "monu" // inside function scope
console.log(name)
}
note: we can't use a variable declared inside of function scope.
Global Scope
Any variable that is outside of the curly braces and function is known as inside of the global scope. e.g.
let name = "monu" // inside of global scope
function printName(){
console.log(name)
}
note: we can use global scope variable inside any block scope and function scope
The Lexical Scope
Now we know SCOPE. Let's understand the lexical scope first with the nesting scope.
Nesting Scope
Scope inside the scope is known as Nesting scope. In nesting scope, we can access the value which is inside the parent of the child scope.
Let us break this with an example
function outerFunction(){ //outer scope
let name = "monu"
function innerFunction(){ // inner scope
console.log(name)
}
innerFunction()
}
// output : monu
as we can see that the outerfunction
has the variable name
but still inside the innerfunction
we can access it. Why is this possible?
Here comes the lexical scope in the picture.
The mechanism which helps innerfunction
to have the access to variables of its lexical scope.
Lexical Scope is the space where the item is created. The item can access all the variables outside of its scope.
In the above example, you can think of what the lexical scope of the inner function
is.
In the following manner.
innerfunction => outerfunction => global scope
Closures
Now we know about how lexical scope works in JavaScript.
Let's understand closures with the above-given example.
In the lexical scope example, we were executing the function inside the outerfunction
scope. But in this time we will return innerfunction
.
1 function outerFunction(){ //outer scope
2 let name = "monu"
4
3 return function innerFunction(){ // inner scope
5 console.log(name)
6 }
7 }
8
9 let result = outerFunction()
10 result() // output : monu
And now the execution of outerFunction
is completed at line number 9 and the result is stored inside the result
variable.
But still somehow when we are executing the result
which stored the returned function from outerFunction
, Still it has access to the variables of its lexical scope although I using it outside of its lexical Scope.
How is this possible?
This is what closure is. Easy right?
You can think of closure which gives you the power to access the variables of
outerfunction
from theinnerfunction
.
That's it.
How closures works
Now we know what is closures but how it works still unclear.
Let's break this one.
To understand how closures work let's see what happened when JavaScript runs the function.
There are a few things that happened under the hood.
- A whole new execution context created
- All the variable inside the function is inside the local execution context
- When the function finishes executing its local memory got deleted and the function pops out from the call stack.
- The result of the function is stored where the function is called. e.g. global execution context, some other local execution context.
Now we know that when the function completes its execution we lost all the data inside of it. But suppose somehow we can hold the data of the function somewhere e.g. some kind of cache. How we can do this? We can do it by just returning a function from a function.
function getName(){
let name = "Monu"
return function (){
console.log(name)
}
}
let name = getName() // return function will hold the data of getName
name() // Monu
The process of holding the data of the environment variable (memories) of function is known as closures. We can only hold the data by returning a function from the inner function.
Note: Every function creation creates a closure. Function declaration in global scope creates a closure with its lexical scope but as we know we directly access the variable of the global scope inside the function so there is no use of closure here.
Application of closures
There are many use cases of closures. These are the following
- Higher-order functions like currying use the closures mechanism
- We can create a function that will run once
- We can create memoize function using closures
- we can write private methods using closures
I will talk about the uses of closure in another blog.
Disadvantages of closures
- The variable declared inside closure is not garbage collected
- Sometimes it slows down the program.
Summary
- There are two types of scopes in JavaScript Local and Global Scope.
- Variable inside the block scope or function scope known as inside the local scope
- Variable outside of block known as an inside the global scope
- Scope rules give the accessibility of the variables
- Lexical scope gives us the power to use the variable outside of the function scope.
- Whenever a function is a return from an outer function closure is formed.
- Closure is way a to hold the data of the function after the execution of the function is completed.
Till then Thank you and show some love to this blog.