Closures are a very important concept in javascript – they are one of the 15 concepts we must learn to be a solid javascript developer. Hence, it is expedient that we at least get acquainted with this VIP.
To keep it simple, a closure is a stateful function that is returned by another function. A stateful function is a function that can remember data from previous executions.
Think of closures as a container used to remember variables and parameters from its parent scope even after the parent scope has been executed.
A closure has access to variables defined within it, variables defined in its parent function, and globally defined variables.
Consider the following blocks of code:
Father = () => {
const fatherVariable = 'Hello world!';
return {
console.log(fatherVariable);
}
}
const Son = Father();
Son();
The above code allows us to store a previously declared code as a variable and execute it. Both Father()
and Son()
return the same output of Hello world!
.
Let’s have a look at another code example that shows a function return the reference of a function within it. It helps explain a very important characteristic of closures, Reusable states.
Reusable states in closures keep the state of outer variables between the multiple function calls. It keeps the reference of the outer variable.
Mother = () => {
let mum = 60;
Daughter = () => {
return 200 - mum;
}
return Daughter;
}
let daughter = Mother();
The variable daughter
returns the value of 200 - 60
, which is 140
. The function Daughter
referenced the variable mum
declared outside of its block but within its parent scope. The Mother
function referenced the Daughter
function in its execution as well. Amazing right!
Closure allows us private variables that are available even after a function task is finished.
Closure enables us to store data in a separate scope and share it only where necessary.
These pros can be summarized in a very important principle of object-oriented programming, encapsulation (others include abstraction, inheritance, and polymorphism).
Closures, as we learned above, have advantages and disadvantages; hence, it is important to understand when they should be used.
Closures are to be used when:
Closures help improve our work speed and prevent a lot of code repetition. This might tempt us to always want to use it, but please hold on a minute.
When not to use Closures( there’s only one I can garner for now):
Namespace privacy is not a necessity for a project that does not require a third-party library or a project with a relatively small codebase. For example:
const compute = (num) => {
return num.value / 4;
}
let first = (digit) => {
this.digit = digit;
this.getDigit = () => {
return this.digit;
};
};
const total = () => {
let b = new first(100);
console.log(compute(b.getDigit()));
}
The example above is a simple code, but it contains three global items. It would be unnecessary to use private namespacing here.
Obviously, most of our projects will require more lines of code. It’s just important to know a scenario where closures should be avoided.
To wrap it up:
“A closure is a combination of a function bundled together(enclosed) with reference to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function scope from an inner function. In Javascript, closures are created every time a function is created, at function creation time.” _ MDN
Thanks for reading!