JavaScript's concept of closure is often misunderstood and confused with lexical scope. To truly grasp the concept of closures, it's essential to have a good understanding of scopes.
What is a Closure?
A closure is a fundamental JavaScript concept where a function retains access to its parent scope, even after the parent function has finished executing. Closures are defined when a function is declared, not when it is executed.
Imagine a child function nested within a parent function. A closure defines the boundaries within which the child function operates. This means the child function can access not only its own variables but also those defined in its parent function and even global scope variables, if any.
Now what does it mean to have access to the scope of its parent even after its parent function has called. Let look at simple example
let x = 1;
function parentFunction() {
let count = 2;
console.log(x);
console.log(count);
function childFunction() {
console.log(x += 1);
console.log(count += 2);
}
return childFunction;
}
const result = parentFunction()
In this example, if we check the console, we'll see 1
and 2
printed, respectively, but we won't see any result from the child function. This is because the child function has not been executed yet; we've only executed the parent function. However, we've also returned the child function, which can now be invoked using result.
To demonstrate this, let's log the result to the console, revealing that it's an anonymous function, which is essentially the child function:
console.log(result);
Now, when we invoke the child function using result(), observe the output:
result()
result()
As we can the child function still it access to count variable even though the parent function has already been called and returned and also the x which is a global variable.
As you can see, the child function still has access to the count variable, even though the parent function has already been executed and returned. It also has access to the global variable x
. However, trying to access count
from the global scope would result in a reference error since it's not accessible at that level.
An Analogy
To simplify our understanding of closures, let's adopt Feyman's Technique:
Imagine you have a cookie jar at home with delicious cookies that you love. However, you don't want anyone in your family to eat them when you're not looking. To keep your cookies safe, you place them inside a special box with a lock. This box is analogous to a closure in JavaScript, safeguarding your cookies from others.
When you want to enjoy a cookie, you take out the key, unlock the box, and retrieve your cookie. You can enjoy as many cookies as you like. Once you're done, you put the remaining cookies back inside the box, lock it again, and hide the key.
This way, your cookies remain safe and private, and you can savor them whenever you want without worrying about someone else taking them.
In JavaScript, a closure is like that special box. It protects specific data or variables, keeping them hidden from the rest of the code. When you need to use these variables, you can open the closure, perform your tasks, and then close it to maintain security. Closures empower programmers to manage and safeguard their data, just like your cookie box protects your cookies from family members!
Conclusion
In conclusion, closures in JavaScript are a powerful concept that allows functions to retain access to their parent scope, even after the parent function has completed its execution. They are not only a fundamental aspect of JavaScript but also a tool that can be harnessed to create private variables and manage data effectively.
As we journey through the fascinating world of JavaScript, I urge you to stay curious and explore more intriguing concepts.
So, stay tuned, and let's learn JavaScript the easy way together!
Further Reading
Excellent article by MDN on closures:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
Top comments (2)
Nice writing! Technically, also the react hook useState is a "closure".
This is a rudimental implementation which for no reason can be used on production code :)
`let state; // old the state outside
function useState(initialValue) {
state = state || initialValue; //set the value
function setState(newValue) {
state = newValue; // update the value
}
return [state, setState];
}`
In summary, a closure is a stateful function
Thank you for the pointing this out @giovannimazzuoccolo I never saw it in that light until now