-
Hajipur, Bihar, 844101
Hajipur, Bihar, 844101
JS Basics
JS Variables & Operators
JS Data Types & Conversion
JS Numbers & Math
JS Strings
JS Dates
JS Arrays
JS Control Flow
JS Loops & Iteration
JS Functions
JS Functions
Function Definitions
Function Parameters
Function Invocation
Function Call
Function Apply
Function Bind
Function Closures
JS Arrow Function
JS Objects
JS Objects
JS Object Properties
JS Object Methods
JS Object Display
JS Object Constructors
Object Definitions
Object Get / Set
Object Prototypes
Object Protection
JS Classes & Modules
JS Async Programming
JS Advanced
JS Destructuring
JS Bitwise
JS RegExp
JS Precedence
JS Errors
JS Scope
JS Hoisting
JS Strict Mode
JS this Keyword
JS HTML DOM
DOM Intro
DOM Methods
DOM Document
DOM Elements
DOM HTML
DOM Forms
DOM CSS
DOM Animations
DOM Events
DOM Event Listener
DOM Navigation
DOM Nodes
DOM Collections
DOM Node Lists
JS BOM (Browser Object Model)
JS Web APIs
Web API Intro
Web Validation API
Web History API
Web Storage API
Web Worker API
Web Fetch API
Web Geolocation API
JS AJAX
AJAX Intro
AJAX XMLHttp
AJAX Request
AJAX Response
AJAX XML File
AJAX PHP
AJAX ASP
AJAX Database
AJAX Applications
AJAX Examples
JS JSON
JSON Intro
JSON Syntax
JSON vs XML
JSON Data Types
JSON Parse
JSON Stringify
JSON Objects
JSON Arrays
JSON Server
JSON PHP
JSON HTML
JSON JSONP
JS Graphics & Charts
Closures are a fundamental concept in JavaScript that allow functions to access variables from an outer scope even after that outer function has finished executing. They are a powerful feature for creating private variables, maintaining state, and building modular and reusable code. Understanding closures is essential for advanced JavaScript programming, especially when dealing with callbacks, event handlers, asynchronous code, and functional programming patterns.
In this tutorial, you will learn what closures are, why they are important, how to use them, practical examples, common mistakes, best practices, and real-world applications.
Closures are important because they allow you to:
Preserve state between function calls
Create private variables that cannot be accessed directly from the outside
Implement modular and reusable code
Work with callbacks, asynchronous operations, and event handlers
Enable functional programming patterns such as currying and partial application
Without closures, managing state or encapsulating variables would require global variables or complex object-oriented patterns, which can lead to code that is harder to maintain and debug.
A closure is created whenever a function is defined inside another function, giving the inner function access to the outer function’s variables. This includes:
Parameters of the outer function
Local variables of the outer function
Variables in the scope chain above the outer function
Even after the outer function has finished executing, the inner function retains access to these variables. This ability to "remember" the environment is what makes closures powerful.
function outerFunction(outerVariable) {
return function innerFunction(innerVariable) {
console.log("Outer: " + outerVariable);
console.log("Inner: " + innerVariable);
};
}
const newFunction = outerFunction("Aarushi");
newFunction("Patna");
Output:
Outer: Aarushi
Inner: Patna
Here, innerFunction has access to outerVariable even though outerFunction has already finished executing. This demonstrates how closures preserve access to the outer scope.
Closures are commonly used to create private variables that cannot be accessed directly:
function createCounter() {
let count = 0;
return function() {
count++;
console.log("Count: " + count);
};
}
const counter = createCounter();
counter();
counter();
counter();
Output:
Count: 1
Count: 2
Count: 3
Here, the count variable is private. It is only accessible through the inner function, preventing external modification.
Closures are often used in event handlers to maintain state:
function setupButton(buttonId, name) {
let clicks = 0;
document.getElementById(buttonId).addEventListener("click", function() {
clicks++;
console.log(name + " clicked " + clicks + " times");
});
}
setupButton("btn1", "Isha");
setupButton("btn2", "Saanvi");
Each button maintains its own clicks count because each event handler forms a closure over its own clicks variable.
Closures can be used for currying, where a function is transformed into a sequence of functions each taking a single argument:
function multiply(a) {
return function(b) {
return a * b;
};
}
const double = multiply(2);
console.log(double(5));
console.log(double(10));
Output:
10
20
The inner function remembers the a argument from the outer function, allowing you to create specialized functions like double.
Forgetting that closures maintain references to variables, which can lead to unintended memory usage
Overusing closures unnecessarily, which can make code harder to read
Assuming closures create a copy of the variable instead of maintaining a reference
Using closures inside loops without understanding variable scope, leading to unexpected behavior
Use closures to encapsulate private data and state
Avoid creating unnecessary closures in performance-critical code
Be aware of memory usage when closures capture large objects
Use meaningful variable names to clarify scope and intent
Combine closures with modular patterns to organize complex applications
Closures are widely used in:
Creating counters and private state variables
Event handlers and callback functions
Functional programming techniques such as currying and partial application
Encapsulation in JavaScript modules
Maintaining state in asynchronous operations such as timers, promises, and AJAX calls
function createCounter() {
let count = 0;
return {
increment: function() {
count++;
console.log(count);
},
reset: function() {
count = 0;
console.log("Counter reset");
}
};
}
const counter = createCounter();
counter.increment();
counter.increment();
counter.reset();
counter.increment();
Output:
1
2
Counter reset
1
function createGreeting(greeting) {
return function(name) {
console.log(greeting + ", " + name + "!");
};
}
const sayHello = createGreeting("Hello");
const sayGoodMorning = createGreeting("Good morning");
sayHello("Aarushi");
sayGoodMorning("Isha");
Output:
Hello, Aarushi!
Good morning, Isha!
function createGame(name) {
let score = 0;
return function(points) {
score += points;
console.log(name + "'s score: " + score);
};
}
const game1 = createGame("Saanvi");
game1(10);
game1(5);
const game2 = createGame("Priya");
game2(7);
Output:
Saanvi's score: 10
Saanvi's score: 15
Priya's score: 7
Closures are a core feature of JavaScript that allow functions to access variables from their outer scope even after the outer function has executed. They are invaluable for maintaining state, creating private variables, building modular and reusable code, and implementing advanced patterns like currying and partial application. Proper understanding and use of closures help you write clean, maintainable, and efficient JavaScript applications.
Q1. Write a function createCounter() that returns another function which increases and returns a private counter each time it's called.
Q2. Create a function greet(message) that returns a function which accepts a name and logs message + name.
Q3. Create a function multiplier(factor) that returns a function to multiply any number by that factor.
Q4. Write a closure that stores a secret message and provides a method to read it but not modify it.
Q5. Create a once() function that allows the given function to run only once and ignores subsequent calls.
Q6. Write a closure that maintains a list and provides addItem() and getItems() methods.
Q7. Create a closure that tracks the number of times a button is clicked (simulate clicks using a function).
Q8. Build a function makeAdder(x) that returns another function which adds x to its argument.
Q9. Create a timer() closure that stores the start time and returns the elapsed time when called again.
Q10. Write a closure-based cache() function that stores and returns computed values based on input (e.g., square of number).
JS Basics
JS Variables & Operators
JS Data Types & Conversion
JS Numbers & Math
JS Strings
JS Dates
JS Arrays
JS Control Flow
JS Loops & Iteration
JS Functions
JS Functions
Function Definitions
Function Parameters
Function Invocation
Function Call
Function Apply
Function Bind
Function Closures
JS Arrow Function
JS Objects
JS Objects
JS Object Properties
JS Object Methods
JS Object Display
JS Object Constructors
Object Definitions
Object Get / Set
Object Prototypes
Object Protection
JS Classes & Modules
JS Async Programming
JS Advanced
JS Destructuring
JS Bitwise
JS RegExp
JS Precedence
JS Errors
JS Scope
JS Hoisting
JS Strict Mode
JS this Keyword
JS HTML DOM
DOM Intro
DOM Methods
DOM Document
DOM Elements
DOM HTML
DOM Forms
DOM CSS
DOM Animations
DOM Events
DOM Event Listener
DOM Navigation
DOM Nodes
DOM Collections
DOM Node Lists
JS BOM (Browser Object Model)
JS Web APIs
Web API Intro
Web Validation API
Web History API
Web Storage API
Web Worker API
Web Fetch API
Web Geolocation API
JS AJAX
AJAX Intro
AJAX XMLHttp
AJAX Request
AJAX Response
AJAX XML File
AJAX PHP
AJAX ASP
AJAX Database
AJAX Applications
AJAX Examples
JS JSON
JSON Intro
JSON Syntax
JSON vs XML
JSON Data Types
JSON Parse
JSON Stringify
JSON Objects
JSON Arrays
JSON Server
JSON PHP
JSON HTML
JSON JSONP
JS Graphics & Charts
