- Javascript Basics Tutorial
- Javascript - Home
- JavaScript - Overview
- JavaScript - Features
- JavaScript - Enabling
- JavaScript - Placement
- JavaScript - Syntax
- JavaScript - Hello World
- JavaScript - Console.log()
- JavaScript - Comments
- JavaScript - Variables
- JavaScript - let Statement
- JavaScript - Constants
- JavaScript - Data Types
- JavaScript - Type Conversions
- JavaScript - Strict Mode
- JavaScript - Reserved Keywords
- JavaScript Operators
- JavaScript - Operators
- JavaScript - Arithmetic Operators
- JavaScript - Comparison Operators
- JavaScript - Logical Operators
- JavaScript - Bitwise Operators
- JavaScript - Assignment Operators
- JavaScript - Conditional Operators
- JavaScript - typeof Operator
- JavaScript - Nullish Coalescing Operator
- JavaScript - Delete Operator
- JavaScript - Comma Operator
- JavaScript - Grouping Operator
- JavaScript - Yield Operator
- JavaScript - Spread Operator
- JavaScript - Exponentiation Operator
- JavaScript - Operator Precedence
- JavaScript Control Flow
- JavaScript - If...Else
- JavaScript - While Loop
- JavaScript - For Loop
- JavaScript - For...in
- Javascript - For...of
- JavaScript - Loop Control
- JavaScript - Break Statement
- JavaScript - Continue Statement
- JavaScript - Switch Case
- JavaScript - User Defined Iterators
- JavaScript Functions
- JavaScript - Functions
- JavaScript - Function Expressions
- JavaScript - Function Parameters
- JavaScript - Default Parameters
- JavaScript - Function() Constructor
- JavaScript - Function Hoisting
- JavaScript - Self-Invoking Functions
- JavaScript - Arrow Functions
- JavaScript - Function Invocation
- JavaScript - Function call()
- JavaScript - Function apply()
- JavaScript - Function bind()
- JavaScript - Closures
- JavaScript - Variable Scope
- JavaScript - Global Variables
- JavaScript - Smart Function Parameters
- JavaScript Objects
- JavaScript - Number
- JavaScript - Boolean
- JavaScript - Strings
- JavaScript - Arrays
- JavaScript - Date
- JavaScript - DataView
- JavaScript - Math
- JavaScript - RegExp
- JavaScript - Symbol
- JavaScript - Sets
- JavaScript - WeakSet
- JavaScript - Maps
- JavaScript - WeakMap
- JavaScript - Iterables
- JavaScript - Reflect
- JavaScript - TypedArray
- JavaScript - Template Literals
- JavaScript - Tagged Templates
- Object Oriented JavaScript
- JavaScript - Objects
- JavaScript - Classes
- JavaScript - Object Properties
- JavaScript - Object Methods
- JavaScript - Static Methods
- JavaScript - Display Objects
- JavaScript - Object Accessors
- JavaScript - Object Constructors
- JavaScript - Native Prototypes
- JavaScript - ES5 Object Methods
- JavaScript - Encapsulation
- JavaScript - Inheritance
- JavaScript - Abstraction
- JavaScript - Polymorphism
- JavaScript - Destructuring Assignment
- JavaScript - Object Destructuring
- JavaScript - Array Destructuring
- JavaScript - Nested Destructuring
- JavaScript - Optional Chaining
- JavaScript - Global Object
- JavaScript - Mixins
- JavaScript - Proxies
- JavaScript Versions
- JavaScript - History
- JavaScript - Versions
- JavaScript - ES5
- JavaScript - ES6
- ECMAScript 2016
- ECMAScript 2017
- ECMAScript 2018
- ECMAScript 2019
- ECMAScript 2020
- ECMAScript 2021
- ECMAScript 2022
- JavaScript Cookies
- JavaScript - Cookies
- JavaScript - Cookie Attributes
- JavaScript - Deleting Cookies
- JavaScript Browser BOM
- JavaScript - Browser Object Model
- JavaScript - Window Object
- JavaScript - Document Object
- JavaScript - Screen Object
- JavaScript - History Object
- JavaScript - Navigator Object
- JavaScript - Location Object
- JavaScript - Console Object
- JavaScript Web APIs
- JavaScript - Web API
- JavaScript - History API
- JavaScript - Storage API
- JavaScript - Forms API
- JavaScript - Worker API
- JavaScript - Fetch API
- JavaScript - Geolocation API
- JavaScript Events
- JavaScript - Events
- JavaScript - DOM Events
- JavaScript - addEventListener()
- JavaScript - Mouse Events
- JavaScript - Keyboard Events
- JavaScript - Form Events
- JavaScript - Window/Document Events
- JavaScript - Event Delegation
- JavaScript - Event Bubbling
- JavaScript - Event Capturing
- JavaScript - Custom Events
- JavaScript Error Handling
- JavaScript - Error Handling
- JavaScript - try...catch
- JavaScript - Debugging
- JavaScript - Custom Errors
- JavaScript - Extending Errors
- JavaScript Important Keywords
- JavaScript - this Keyword
- JavaScript - void Keyword
- JavaScript - new Keyword
- JavaScript - var Keyword
- JavaScript HTML DOM
- JavaScript - HTML DOM
- JavaScript - DOM Methods
- JavaScript - DOM Document
- JavaScript - DOM Elements
- JavaScript - DOM Forms
- JavaScript - Changing HTML
- JavaScript - Changing CSS
- JavaScript - DOM Animation
- JavaScript - DOM Navigation
- JavaScript - DOM Collections
- JavaScript - DOM Node Lists
- JavaScript Miscellaneous
- JavaScript - Ajax
- JavaScript - Async Iteration
- JavaScript - Atomics Objects
- JavaScript - Rest Parameter
- JavaScript - Page Redirect
- JavaScript - Dialog Boxes
- JavaScript - Page Printing
- JavaScript - Validations
- JavaScript - Animation
- JavaScript - Multimedia
- JavaScript - Image Map
- JavaScript - Browsers
- JavaScript - JSON
- JavaScript - Multiline Strings
- JavaScript - Date Formats
- JavaScript - Get Date Methods
- JavaScript - Set Date Methods
- JavaScript - Modules
- JavaScript - Dynamic Imports
- JavaScript - BigInt
- JavaScript - Blob
- JavaScript - Unicode
- JavaScript - Shallow Copy
- JavaScript - Call Stack
- JavaScript - Reference Type
- JavaScript - IndexedDB
- JavaScript - Clickjacking Attack
- JavaScript - Currying
- JavaScript - Graphics
- JavaScript - Canvas
- JavaScript - Debouncing
- JavaScript - Performance
- JavaScript - Style Guide
- JavaScript Useful Resources
- JavaScript - Questions And Answers
- JavaScript - Quick Guide
- JavaScript - Functions
- JavaScript - Resources
JavaScript - Closures
What is Closure?
The concept of closures in JavaScript allows nested functions to access variables defined in the scope of the parent function, even if the execution of the parent function is finished. In short, you can make global variables local or private using the closures.
A JavaScript closure is basically a combination of the function and its lexical environment. This allows an inner function to access the outer function scope. A closure is created every time a function is created at the function creation time.
Before you start learning the concept of closures, you need to know the concept of lexical scoping, nested functions, and returning functions.
Lexical Scoping
In JavaScript, the lexical scoping is a concept in which the scope of the variables is determined at the code compilation time based on the structure of the code. For example, the nested function can access the variables from the parent function's scope is called lexical scoping.
Nested Function
You can define the function inside the function, and the inner function is called the nested function. Let's learn it via the example below.
Example
In the example below, we have defined the inner() function inside the outer() function. Also, the inner() function is executed inside the outer() function.
When we execute the outer() function, it also executes the inner() function, a nested function.
<html> <body> <p id = "demo"> </p> <script> const output = document.getElementById("demo"); function outer() { output.innerHTML += "The outer function is executed! <br>"; function inner() { output.innerHTML += "The inner function is executed! <br>"; } inner(); } outer(); </script> </body> </html>
Output
The outer function is executed! The inner function is executed!
Returning Function
When any function returns the function instead of a value or variable, it is called the returning function. Let's look at the example below.
Example
In the below code, the outer() function returns the function definition, and we store it in the 'func' variable. After that, we use the 'func' variable to invoke a function stored in that.
<html> <head> <title> JavaScript - Returning function </title> </head> <body> <p id = "demo"> </p> <script> const output = document.getElementById("demo"); function outer() { output.innerHTML += "The outer function is executed! <br>"; return function inner() { output.innerHTML += "The inner function is executed! <br>"; } } const func = outer(); func(); func(); </script> </body> </html>
Output
The outer function is executed! The inner function is executed! The inner function is executed!
Now, you learned the prerequisite required to learn the closures.
The definition of JavaScript closure is a bit confusing, but we will learn the closure concept step by step so it will be clear to you.
A Counter Dilemma
For example, you create the counter to increment and decrement the variable. As shown below, you need to use the global variable for the counter.
Example
In the example below, the 'cnt', a global variable is initialized with 100. Whenever the decrement() function is executed, it decreases the value of the 'cnt' variable by 1.
<html> <body> <p id = "demo"> </p> <script> const output = document.getElementById("demo"); var cnt = 100; function decrement() { cnt = cnt - 1; output.innerHTML += "The value of the cnt is: " + cnt + "<br>"; } decrement(); decrement(); decrement(); </script> </body> </html>
Output
The value of the cnt is: 99 The value of the cnt is: 98 The value of the cnt is: 97
The above code perfectly works as a decrement counter, but the problem is 'cnt' variable can be accessed in the code anywhere, and any part of the code can change it without executing the decrement() function.
Here, JavaScript closure comes into the picture.
Example: JavaScript Closures
The counter() function returns the decrement() function in the example below. The 'cnt' variable is defined inside the counter() function rather than in the global scope.
The decrement() function decreases the value of the 'cnt' by 1 and prints in the output.
The 'func' variable contains the decrement() function expression. Whenever you execute the func(), it calls the decrement() function.
<html> <body> <p id = "demo"> </p> <script> const output = document.getElementById("demo"); function counter() { let cnt = 100; // Works as a global variable for the decrement function. return function decrement() { cnt = cnt - 1; output.innerHTML += "The value of the cnt is: " + cnt + "<br>"; } } const func = counter(); // Returns the decrement() function expression func(); func(); func(); </script> </body> </html>
Output
The value of the cnt is: 99 The value of the cnt is: 98 The value of the cnt is: 97
Now, let's remember the definition of closure again. It says that the nested function can access the variables from the outer function's scope even if the execution of the outer function is finished.
Here, the execution of the counter() function is finished. Still, you can call the decrement() function and access the 'cnt' variable with an updated value.
Let's look at another example of closure.
Example
In the example below, the name() function returns the getFullName() function. The getFullName() function merges the string with the 'name' variable, defined in the outer function's scope.
<html> <head> <title> JavaScript - Closure </title> </head> <body> <p id = "demo"> </p> <script> const output = document.getElementById("demo"); function name() { let name = "John"; return function getFullName() { return name + " Doe"; } } const fullName = name(); output.innerHTML += "The full name is " + fullName(); </script> </body> </html>
Output
The full name is John Doe
Benefits of Closure
Followings are some benefits of the closures in JavaScript −
Encapsulation − The closure allows developers to hide or encapsulate the data. It makes data private and inaccessible from the global scope. So, you can expose only the required variables and functions and hide other internal details of the code.
Preserving State − The function remembers its lexical scope even if the execution of the outer function is completed. So, developers can maintain the state as we were maintaining the state of the counter in the above examples.
Improved memory efficiency − The closure allows you to manage memory efficiently, as you can only retain access to the necessary variables and don't need to define the variables globally.