What is Closures?
A closure is the combination of a function bundled together with references to its the lexical environment. In other words, A Closure is nothing but a function inside another function. This closure function can access the variables inside its own scope, the outer function's variables and the global variables.
What is Lexical scoping
When a function is defined in another function, the inner function has access to the outer function’s variables. This behavior is called lexical scoping.
Example of Closure:-
function outerFunc() {
// the outer scope
let outerVar = 'Hello World';
function innerFunc() {
// the inner scope
console.log(outerVar); // 'Hello World'
}
return innerFunc;
}
const inner = outerFunc();
inner();
Output:
Hello World
Explanation:
In the above example, the outer function outerFunc
creates a variable outerVar
, which is then being used inside the inner function innerFunc
. Within the inner function, there is no variable declared, but due to closure, it can access the variable declared within the outer function.
What is Scope
A scope in JavaScript defines what variables you have access to. There are two kinds of scope – global scope and local scope.
Closure Scopes :-closure has three scopes:
Local Scope
Outer Functions Scope
Global Scope
Let see understand through example
// global scope
var scoreVar = 5;
function sum(scoreOne){
return function(scoreTwo){
return function(scoreThree){
// outer functions scope
return function(scoreFour){
// local scope
return scoreOne + scoreTwo + scoreThree + scoreFour + scoreVar;
}
}
}
}
console.log(sum(20)(10)(30)(60)); // Ouput 125
JavaScript closures in a loop
for (var i = 1; i <= 3; i++) {
setTimeout(function () {
console.log('after ' + i + ' second(s):' + i);
}, i * 1000);
}
Output
after 4 second(s):4
after 4 second(s):4
after 4 second(s):4
The code shows the same message.
What we wanted to do in the loop is to copy the value of i
in each iteration at the time of iteration to display a message after 1, 2, and 3 seconds.
The reason you see the same message after 4 seconds is that the callback passed to the setTimeout()
a closure. It remembers the value of i
from the last iteration of the loop, which is 4.
In addition, all three closures created by the for-loop share the same global scope access the same value of i
.
To fix this issue, you need to create a new closure scope in each iteration of the loop.
There are two popular solutions: IIFE & let
keyword.
What is the practical use for a closure in JavaScript?
allows for the nesting of functions and grants the inner function full access to all the variables and functions defined inside the outer function (and all other variables and functions that the outer function has access to). A closure is a code block with bound variables - it "catches" its variables from their outer context - but it is independent from that same context. A practical use in javascript is when defining events or callbacks - you declare a closure to be executed on the click of a button, for instance, but this closure can reference variables declared on the caller scope.
Benefit of Closure
The benefit of Closure is to preserve local variables within the scope Maintain state between each function call.
Why Closures?
Now that we’ve cleared that up, let’s cover the why. Why would you want to care about closures? Granted, closures make a lot of sense in the functional programming world, after all, you need functions to be first-class citizens in order to have closures. So if you’re going full OOP with your JavaScript code, you’re probably not interested or even see the need for such a concept. And that is perfectly fine, but mind you, JavaScript is not a completely OOP language, even though ES6 has tried to bridge that gap by adding concepts, such as classes. So, let me show you some benefits of mixing things up a bit and I’ll let you decide then, if closures are for you or not.