Advanced JavaScript: Chapter 1 - Closures in Javascript
Abhinandan Mishra
Specialist Programmer @Infosys | DSA, System Design | JavaScript, React, Angular, Next.js, .NET Core, FastAPI | Frontend, Backend | Web3
Overview ??
Closures are one of the important concepts in JavaScript and are most widely used by developers either knowingly or unknowingly. A good understanding of this concept can improve the code and will provide a better understanding of how code is working internally and that will help in finding bugs and expecting the outcome.
Scoping in javascript ??
Before understanding closure, let's understand what is scope in JavaScript. Before ES6, javascript had only two types of scoping function scope?and?global scope, which is a variable that can be either function scoped if defined inside a function or global scoped if defined outside the function.
For example, in the below code, the variable x is defined inside the if-else block but it can be accessed outside the block also because it's globally scoped.
// there's no concept of block scope before ES6
if (Math.random() > 0.5) {
? var x = 1;
} else {
? var x = 2;
}
console.log(x);
// Output: output will be 1 or 2 based on the condition
// but it will not give any error
A block is a pair of braces ({...}) used to group multiple statements.
In ES6, JavaScript introduced the?let?and?const?declarations, which allow us to create block-scoped variables but those remain in a temporal dead zone until the variable gets initialized.
A temporal dead zone (TDZ) is the area of a block where a variable is inaccessible until the moment the computer completely initializes it with a value.
Understanding Temporal Dead Zone by an example ??
// block starts here
{
// name's TDZ starts here (at the beginning of this block’s local scope)
// name's TDZ continues here
// name's TDZ continues here
console.log(name); // returns ReferenceError because name’s TDZ continues here
// name's TDZ continues here
// name's TDZ continues here
let name = "Abhinandan Mishra"; // name's TDZ ends here
// name’s TDZ does not exist here
// name’s TDZ does not exist here
}
// block ends here
A variable's temporal dead zone starts from the first line of the code and continues till the variable gets initialized.
For const variable intialization should be done at the time of decalaration.
Closure in JavaScript ????
The closure is basically some functions bundled together that have references to their surrounding state ( known as lexical environment ).
In simple words, closure provides access to variables of the outer scope's function to inner functions.
Now, while talking about the scope we shouldn't talk about the var keyword because it's globally scoped and hence can be accessed from anywhere in the code. Our main focus will be on block-scoped variables that is let or const keyword variables.
Let's understand the closure by the following example:-
function createMailTemplate(message) {
function createMail(name) {
const mail = `Hi ${name}, ${message}`;
return mail;
};
return createMail; // function is returned here
}
const introMail = createMailTemplate("Welcome to fullstack insights newsletter");
const thankyouMail = createMailTemplate("Thank you for visiting my blog!");
console.log(introMail("Abhinandan"));
// Output :- Hi Abhinandan, Welcome to fullstack insights newsletter
console.log(thankyouMail("Mishra"));
// Output :- Hi Mishra, Thank you for visiting my blog!
In the above example, we have created a function createMailTemplate, that takes a message as a parameter and returns a createMail function that takes a name as a parameter. createMail uses the message variable of the createMailTemplate function and name parameter to create the mail and return it.
Now, the message parameter that is passed in the createMailTemplate is a block-scoped variable so it should be accessed in the scope of createMailTemplate only and we know that after a function gets executed its variables get cleared from the memory.
const introMail = createMailTemplate("Welcome to fullstack insights newsletter");
In the above line of code, the createMailTemplate function gets executed and the message variable gets cleared from the memory.
领英推荐
console.log(introMail("Abhinandan"));
// Output :- Hi Abhinandan, Welcome to fullstack insights newsletter
So, Ideally, it shouldn't be accessible when we call the introMail function. But actually, it somehow retains the value of the message variable and returns the output shown above.
This behavior of retaining the value of the variable or having access to the value of variables defined in outer functions by inner functions is known as Closure.
Concept behind closure ????♂?
The basic concept behind closure in JavaScript is scope chaining. A scope chain is a chain of scopes starting from a global scope and to a particular scope.
Let's understand the scope chaining with an example:-
let scope = "global_scope";
let global_var = "defined globally";
let func_var = "func_var_defined_globally";
function func1() {
let scope = "func1_scope";
function func2() {
let scope = "func2_scope";
let global_var = "defined inside func2";
console.log("Accessing variables in func2 scope")
console.log("scope:", scope);
console.log("global_var:", global_var);
console.log("func_var:", func_var);
}
console.log("Accessing variables inside func1 scope")
console.log("scope:", scope);
console.log("global_var:", global_var);
return func2;
}
const fn = func1(); // executed function 1
fn(); // executed func2 returned by func1
Output :-
Accessing variables inside func1 scope
scope: func1_scope
global_var: defined globally
Accessing variables in func2 scope
scope: func2_scope
global_var: defined inside func2
func_var: func_var_defined_globally
Step-by-step explanation:-
1. Global Variable Declarations: In JavaScript, variables can be declared with different scopes. In this example, we start by declaring several variables in the global scope:
let scope = "global_scope";
let global_var = "defined globally";
let func_var = "func_var_defined globally";
2. Function Declaration (func1): Next, we declare a function named func1. Inside func1, a new variable named scope is declared with a local scope specific to func1. Additionally, within func1, another function named func2 is defined.
3. Accessing Variables within func1:
4. Returning a Function (func2): The func1 function returns the func2 function. This is possible because JavaScript functions can be treated as first-class citizens, allowing them to be returned from other functions.
5. Execution of func2:
The JavaScript scope chain is a mechanism that allows functions to access variables not only in their own local scope but also in their parent scopes, following a hierarchical chain until a variable with the specified name is found or the global scope is reached.
Usage of closure ????♂?
There are so many use cases of closures:-
There can be many other uses of closure that you will encounter while building real-world applications.
That's all for the scope of this article, hope you've added some data to your knowledge scope.
Happy Coding!
Swami Ramanand teerth Marathwada University Nanded
7 个月Nice
Salesforce developer intern @TheSmartBridge | 1x Salesforce Certified ? | Trailhead Ranger | Salesforce Enthusiast | 28x Superbadges | GitHub Campus Expert ??| B.Tech - ECE Final Year @MMMUT, Gorakhpur
1 年Thanks for sharing sir! ?
SDE - I @Expedia Group | Ex- SDE - Intern @Juspay | Siemens Scholar - Batch 07 | ICPC Regionalist '21
1 年Helpful, Looking forward to more such articles ?
Specialist Programmer @ Infosys | JavaScript, Angular, .NET Core | Full Stack Developer |
1 年Your examples made grasping the topics much easier - great job!
System Engineer
1 年Nicely explained everything ????