You will probably get asked what a closure is at some point in your web dev career, possibly at an interview, and it's one of those things that can be frustratingly difficult to explain under pressure.
For concepts like this, I like finding or creating a concise example. This helps them sink into my memory better than bookmarking and re-reading long articles.
This approach of example first, explanation later is what works for me, hopefully it helps you too!
Creating a function that returns another function
const bigFunction = () => {
let outsideVariable = "abcd"
return smallFunction = () => {
return outsideVariable;
}
}
Here we have a function bigFunction that returns another function smallFunction.
smallFunction itself accesses and returns a variable which is declared outside smallFunction, but inside bigFunction
Assigning the returned function to a variable
const bigFunction = () => {
let outsideVariable = "abcd"
return smallFunction = () => {
return outsideVariable;
}
}
const newSmallFunction=bigFunction();
Here, we're assigning the return value of bigFunction to a new variable. Since bigFunction returns smallFunction, this new variable will be a function.
This code is essentially the same as:
const newSmallFunction=smallFunction
Looks like we have a problem?
If we go back and look at the definition of smallFunction, this line of code can now be thought of as:
const newSmallFunction = () => {
return outsideVariable;
}
Looking at this, it would seem that outsideVariable is an undefined variable, since newSmallFunction is in global scope, and outsideVariable is not!
console.log(newSmallFunction())
This should error and say "outsideVariable is undefined" right?
This would be the case if smallFunction was assigned to newSmallFunction with no memory of where it was defined!
Luckily, javascript has our backs!
And this is where closures come into the picture.
All functions in javascript remember where they were created/defined, and they remember the variables that were in scope when they were defined.
Since smallFunction has access to outsideVariable when it is defined, it carries that value along with it like a backpack.
When we call bigFunction to assign smallFunction to a global variable, it does not panic because outsideVariable is not available in global scope, it can just reach into this closure backpack to read the value of outsideVariable.
This combination of a function and the variables it has access to when it is defined, is called a closure.
I would highly recommend trying this example in a browser console, and using console.dir() to see closure in action.
For those unfamiliar with console.dir(), according to MDN, console.dir shows an interactive list of the properties of an object.
Here is the output from running
console.dir(newSmallFunction)
The scopes property is what we want to take note of.
Seeing Closure as one of the scopes available to the function really helped me understand how this works.
The variable outsideVariable is made available to newSmallFunction via a closure, and we can clearly see this in the console.dir output (it even shows us where outsideVariable came from - bigFunction)
Here is the entire example in one snippet for you to play around with.
const bigFunction = () => {
let outsideVariable = "abcd"
return smallFunction = () => {
return outsideVariable;
}
}
const newSmallFunction=bigFunction();
console.log(newSmallFunction());
console.dir(newSmallFunction)
Conclusion
I hope this has helped! I used this example to explain closure at an interview and received very positive feedback, so it's definitely been battle tested!
Also, this post is adapted from of a talk I gave at the Founders and Coders bootcamp about some tricky javascript concepts, and I will be posting some more excerpts from the talk soon!
Thanks for reading!
Top comments (11)
Thanks! Thought closure meant when you tell your ex not to call you ever again :P
In JS, closure is still having your ex's number in your phone ;)
😅this works too I guess
Thanks for Explaining me this Hard Topic.
glad it helped!!
nice article bud!
Thanks Tom!
That is as neat as someone can explain closures. Good job bro 🕺👾
So clearly explained Reuben!
Thanks! Here's to more posting✌️
Great memory refresh!
I would, however, consider using a real-world example in addition to the one you used, since this concept can feel a little abstract.