Before going to closure, let's first see what is lexical scoping?
See the following example to understand the lexical scoping:
var name = "html5awesome";
A function displayName() contains a locale variable name & has created a locale function showName(). Here showName() is an inner function & which is available only within the body of displayName(). In the showName() function we haven't defined any locale variable but as the inner function has access to a locale variable of the outer function, the name variable can be accessed by the showName() which is declared in the displayName() outer function.
By the example of lexical scoping, we can describe how the parser takes & uses variable names when functions are nested. The meaning of lexical scoping itself says that it finds a variable declared within the source code & determines whether it is available or not? Nested functions always have access to the variables declared in the outer scope.
Now, let's see what is the closure?
var name = "html5awesome";
var fun1 = displayName();
This code will run the same as above. But the difference is that before executing the displayName() function will return a showName() function that means the inner function will return from the outer function.
In the above example, fun1 is a reference to the instance of the displayName() that is created when function fun1() runs. The instance of displayName() creates a lexical environment in which variable name exists. So, that is the reason when the reference of displayName() that fun1() gets invoked, the variable "name" is available for use & you will get the alert message with html5awesome text.
What is a Practical Closure?
Closure helps us to associate data to the methods in the lexical scope, in which you can operate that data. It is the same as Object-Oriented Programming where an object allows you to associate data i.e. object properties with one or more methods. Accordingly, you can use a closure anywhere that you might use the object only with a single method.
For example, suppose we want to add buttons on the page, which adjusts the text size. You can achieve it by defining the font size in the body element & accordingly, you will adjust the font size of other elements using em. See the below code, for the same -
font-size : 12px;
font-size : 1.5em;
font-size : 1.2em
The script to run the above code is
document.body.style.fontsize = size + 'px';
var size1 = sizer(12);
var size2 = sizer(14);
var size3 = sizer(16);
here, size1, size2,size3 are now functions that resize the body text to 12, 14 & 16 px respectively. We can attach them to buttons to work on as follows
document.getElementById('btn1').onClick = size1;
document.getElementById('btn2').onClick = size2;
document.getElementById('btn3').onClick = size3;
<button id = "btn1">Size 12</button>
<button id = "btn1">Size 14</button>
<button id = "btn1">Size 16</button>
You can use the above code to show text in different font sizes according to the button.
Closure Scope Chain
Every closure have 3 scopes, as follows
Locale Scope (own scope)
Outer Functions Scope
Here, outer functions are themselves the nested functions. Access to the scope of the outer function includes the enclosing scope of the outer function which effectively creates the chain of the function scopes. To check how will this work out, see the following example -
var i =10;
Here, the output will be 26.
In the above example, there is a series of the nested functions, in which they all have access to the outer function's scope. So, we can say that closure has access to all the outer functions.
Points to remember
● Don't use closure in the loop, because it will not execute the program as expected. The reason behind this is that when we define a variable or object for one loop it has access to that loop only. According to the closure property, an object can be accessed by the outer function or nested function, but it is not the case with loops. As when we are trying to use nested loops an iterator sets its value initially to 0 or 1 as per the requirement. So, you don't get the expected output.
● Don't create functions within other functions, if closures are not needed for the particular task, it will not be good for both performance & memory consumption.