You might've heard about closures in JavaScript, but you don't actually know what it is or why it is used. In this blog I'll give details about closures that you need to know.
What are closures?
As per the MDN docs,
A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment)
In other words, a closure gives you access the outer function's variables inside the inner function. Closures are created every time a function is created. Let's take a look at an example
function sayHello(name) {
return function displayMessage() {
console.log(`Hello ${name}`);
};
}
const sayHelloToJohn = sayHello("John Doe");
sayHelloToJohn(); // Hello John Doe
In the above example, I've created a function sayHello
which takes a parameter name
. This function returns another function which log the name(from outer function) to the console.
So, What happens is that when we call the sayHello
function, the inner function is returned and assigned to sayHelloToJohn
and when we call this function, Hello John Doe
is logged onto the console.
But, you might be asking yourself that isn't the validity of local variables inside function expires once the function is finished executing? So, how come this inner function lets you access the local variable of it's parent function?
The reason is functions in JavaScript form closures. A closure is a combination of function and lexical environment within which the function was created. This lexical environment consists of any local variables that were present at the time the closure was created.
In this case, sayHello
is a reference to the instance of the function displayMessage
that is created when sayHello
runs. This instance of displayMessage
maintain a reference to its lexical environment within which the variable name
exists. For this reason, when the inner function is called the variable name
is available for use
That's what closures is all about in JavaScript!
Another example
Let's take a practical example to understand it better.
function changeColor(color) {
return function () {
document.getElementById("btn").style.backgroundColor = color;
};
}
const changeColorToBlue = changeColor("blue");
const changeColorToRed = changeColor("red");
In this example, we create a changeColor
function that accepts a color
parameter and returns a function which changes the background color of the button.
changeColorToBlue
and changeColorToRed
are now functions which when invoked will change the background color of the button to the respective argument passed to the changeColor
function.
Private methods with closures
Closures can help you to actually emulate private methods. This could help in restricting access to variables or methods. The following example below demonstrates how public function access private members.
const createCounter = function (initialValue) {
let counterVar = 0;
function increment() {
counterVar = counterVar + 1;
}
function decrement() {
counterVar = counterVar - 1;
}
function getCounter() {
return counterVar;
}
return { increment, decrement, getCounter };
};
const counter = createCounter(0);
console.log(counter.getCounter()); // 0
counter.increment();
counter.increment();
console.log(counter.getCounter()); // 2
counter.decrement();
console.log(counter.getCounter()); // 1
Conclusion
That's all about closures in short. In case you want to dig deeper, you can also refer to the MDN Docs
My Socials
Twitter - shaancodes
Instagram - shaancodes
GitHub - shaancodes