In JavaScript, closure is a fundamental and powerful concept.
A closure is formed when a function is defined within another function, allowing the inner function to access the outer function's variables and parameters, even after the outer function has finished execution.
This enables the inner function to "remember" the environment in which it was created.
Here's a example to illustrate closures:
function addOuterFunction(num1) { // This inner function is a closure function innerFunction(num2) { return num1 + num2; // innerFunction can access 'x' from the outer scope } return innerFunction; } // Creating a closure by calling addOuterFunction const innerAddFunction = addOuterFunction(12); // Using the closure to add 8 to the 'num1' from addOuterFunction const sum = innerAddFunction(8); console.log(sum); // Output: 20 function outerFunction(num1) { // This inner function is a closure function innerFunction(num2) { return num1 * num2; // innerFunction can access 'x' from the outer scope } return innerFunction; } // Creating a closure by calling outerFunction const closureInstance = outerFunction(4); // Using the closure to multiply 10 to the 'num1' from outerFunction const result = closureInstance(10); console.log(result); // Output: 40
`innerFunction` is a closure because it is defined inside `outerFunction` and references the variable `num1` from its outer scope.
When `outerFunction` is called with the argument `4`, it returns `innerFunction`, creating a closure where `num1` is fixed to the value `4`.
Later, when `closureInstance` is invoked with the argument `10`, it multiplies `10` to the remembered value of `num1` (which is `4`), resulting in `40`.
function createCounter() { let count = 0; // 'count' is a private variable within the closure return function () { return ++count; }; } const counter = createCounter(); console.log(counter()); // Output: 1 console.log(counter()); // Output: 2 console.log(counter()); // Output: 3
`createCounter` returns a closure that has a private variable count.
The returned function can access and modify the count, effectively creating a counter that persists in its state between calls.
Closures are powerful because they allow us to create private variables, and functions and encapsulate functionality.