Table of contents
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 to an outer function's scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time.
That was given definition at MDN. Let's understand by our own simple explanation.
We can compare closure with boundary wall. We know when we create a boundary wall for our home it will create an inner environment for our home and surrounding space.
Exactly what was happened when we create a function. The function will create a lexical environment which is simply closure.
Let's watch the picture given bellow.
In general, no can get inside the boundary wall but if anyone has the key, he can access. But the people who are already inside the boundary they can roam around the space. Even now they can get access to home if they don't have the key. But the people inside the home can access to home and outer side of home even out of the boundary wall.
Let's see a code snippet like the picture.
function boundaryWall() {
let x = 10;
function homeOfOne() {
console.log(`I am from home one and my variable value is ${x}`);
}
function homeOfTwo() {
let x = 20;
console.log(`I am from home two and my variable value is ${x}`);
}
homeOfOne();
homeOfTwo();
console.log(`I am from boundaryWall and my variable value is ${x}`);
}
boundaryWall();
Output
I am from home one and my variable value is 10
I am from home two and my variable value is 20
I am from boundaryWall and my variable value is 10
Let's analize the code. console.log()
from homeOfOne()
print x
value as 10. What was happened there? Let's understand this.
The homeOfOne()
function try to find the value inside its scope. I mean we already know when we create any function, the function will create an environment for the function and also create a scope. In this scope no outer function can access what we saw as like in first picture.
Let's back to our code snippet. In homeOfOne()
had no variable called x
. So, it goes outside of the function and try to find the variable of its parent. Does the variable exist or not in its parent? Yah, this time he gets his value.
Now console.log()
from homeOfTwo()
print x value as 20. This time the function homeOfTwo()
has a variable called x
. So, it gets the value of 20 and also don't have to go to outside of function scope.
And the last one from boundaryWall()
also print x's value as 10. Which homeOfOne()
also got.
Now look another code snippet.
function boundaryWall() {
let x = 10;
}
boundaryWall();
console.log(`I am from outside of boundaryWall and my variable value is ${x}`);
Output: ReferenceError: x is not defined
We can see there that output is saying x is not defined
but we defined the variable. Yes, here comes the closure. Because of closure we can't access the value of x
.
Then watch out another code snippet.
if (true) {
let x = 10;
}
console.log(`I am from outside of if block and my x value is ${x}`);
Output: ReferenceError: x is not defined
But But But
if (true) {
var x = 10;
}
console.log(`I am from outside of if block and my x value is ${x}`);
Output: I am from outside of if block and my x value is x
Why is there difference?
Surprise! Surprise! Surprise!
Here is the twist! if we define variable using var
key word it will get the value but if we use let
or const
which was introduced later on ES6.
We will talk about on this matter in any other blog. Have a nice day.