Closures in JavaScript enable functions to retain access to variables from their outer scope even after the outer function has finished executing.
What is a Closure?
A closure is created when a function is defined inside another function and remembers the variables in its outer function.
Example
function outerFunction(outerVariable) {
return function innerFunction(innerVariable) {
console.log(`Outer: ${outerVariable}, Inner: ${innerVariable}`);
};
}
const newFunc = outerFunction("Hello");
newFunc("World"); // Output: Outer: Hello, Inner: World
Why Use Closures?
Closures are useful for:
- Data encapsulation: Protect variables from being modified directly.
- Creating private variables: Simulating private scope.
- Callbacks and event handlers: Maintaining state across function calls.
- Currying: Breaking functions into smaller, reusable functions.
Practical Examples of Closures
1. Data Encapsulation
function counter() {
let count = 0;
return function () {
count++;
console.log(count);
};
}
const increment = counter();
increment(); // Output: 1
increment(); // Output: 2
2. Private Variables
function createPerson(name) {
return {
getName: function () {
return name;
},
setName: function (newName) {
name = newName;
},
};
}
const person = createPerson("Alice");
console.log(person.getName()); // Output: Alice
person.setName("Bob");
console.log(person.getName()); // Output: Bob
3. Function Currying
function multiply(a) {
return function (b) {
return a * b;
};
}
const double = multiply(2);
console.log(double(5)); // Output: 10
4. Maintaining State in Asynchronous Code
function delayedMessage(message, delay) {
return function () {
setTimeout(() => {
console.log(message);
}, delay);
};
}
const sayHello = delayedMessage("Hello, World!", 2000);
sayHello(); // Output (after 2s): Hello, World!
Conclusion
Closures are a fundamental concept in JavaScript that enable powerful programming patterns. By understanding closures, you can write more efficient, modular, and maintainable code.