Closures are a fundamental concept in JavaScript that play a crucial role in how functions work. Understanding closures is essential for unlocking the full potential of JavaScript. So let’s dive into this topic and explore what closures are all about.
In JavaScript, when a function is executed, it carries with it the scope that was in place when it was defined, rather than the state that is in place when it is called. This scope consists of the variables that are visible to the function.
A closure is a mechanism by which a function remembers and can access variables from its parent scope. It essentially creates a bond with the variables it needs to keep track of. This ability to access variables from an outer scope even after the outer function has finished executing is what makes closures so powerful.
To illustrate this concept, let’s consider a simple example:
const bark = (dog) => {
const say = `${dog} barked!`;
(() => console.log(say))();
}
bark(`Roger`);
In this example, the function bark
creates a closure by accessing the say
variable defined in the outer scope. The closure allows the inner function to access and log the value of say
, giving the expected output of Roger barked!
.
Closures also enable us to return functions that retain access to their parent scope. Here’s an example:
const prepareBark = (dog) => {
const say = `${dog} barked!`;
return () => console.log(say);
}
const bark = prepareBark(`Roger`);
bark();
In this case, the prepareBark
function returns an inner function that still has access to the say
variable. When we call bark()
, it logs Roger barked!
to the console.
To further demonstrate the power of closures, let’s see how we can reuse the prepareBark
function for different dogs:
const prepareBark = (dog) => {
const say = `${dog} barked!`;
return () => {
console.log(say);
}
}
const rogerBark = prepareBark(`Roger`);
const sydBark = prepareBark(`Syd`);
rogerBark();
sydBark();
In this example, we create closures for both rogerBark
and sydBark
, each with their own unique say
variable. When we call these functions, they log Roger barked!
and Syd barked!
respectively, demonstrating that the state of the say
variable is preserved across different closures.
To summarize, closures in JavaScript allow functions to access variables from their parent scopes, even after the parent function has finished executing. This feature provides flexibility and power when working with functions. By understanding closures, you can leverage their benefits and write more robust and efficient JavaScript code.