Demystifying Closures: The Power of Scope Chaining
What is a Closure?
A closure in JavaScript is like a function with a backpack. Inside that backpack are all the variables from the outer function that the inner function may need. In layman's terms, a closure is a function (inner function
) bundled with its surrounding state (outer function
), allowing the inner function to access variables from an external scope.
How Does It Work?
The crux of closures lies in JavaScript's scope chaining. When a function is defined inside another function, it forms a lexical scope. This lexical scope allows the inner function to access variables from its surrounding or outer scopes.
1function outerFunction(outerVariable) {
2 return function innerFunction(innerVariable) {
3 console.log(`Outer Variable: ${outerVariable}`);
4 console.log(`Inner Variable: ${innerVariable}`);
5 }
6}
7
8const closureInstance = outerFunction('outer'); // outerFunction has returned
9closureInstance('inner'); // Still can access 'outerVariable'
The Magic: Persisting State
What's magical about closures is that they remember the environment in which they were created. Even if the outer function has finished executing and its variables are out of scope, the inner function still retains access to them.
Scope Chaining in Action
The ability for closures to access variables from outer scopes even after those scopes have exited is possible due to JavaScript's scope chaining mechanism.
1function countdown(start) {
2 let counter = start;
3 return function () {
4 console.log(counter);
5 counter--;
6 };
7}
8
9const countFromFive = countdown(5);
10countFromFive(); // Output: 5
11countFromFive(); // Output: 4
xxxxxxxxxx
// Outer function
function adder(a) {
// Inner function/Closure
function add(b) {
console.log(a + b);
}
return add;
}
var add5 = adder(5);
var add10 = adder(10);
add5(10); //15
add10(10); //20