Introduction to JavaScript Closure
We have a great and most frequently used function in a javascript programming language named closures. By using the closures an inner function can access the variables and parameters of its outer function inside its body. This opens up a huge amount of possibilities and benefits where this can be used. To understand closures it is required to know the scope of the variables in javascript. Javascript closures only come into the picture when there is the nesting of functions.
A closure function has access to three scope chains namely, its scope, outer function’s scope, and global variables scope. This means that a closure function can access its variables and arguments defined in its closed curly braces {…}, the outer function’s variables and arguments as well as the global variables which are declared.
Examples to Implement JavaScript Closure
Let us see how this can be implemented with the help of an example.
Example #1
Code:
<!DOCTYPE html>
<html>
<body>
<p>Demonstration of Javascript Closure</p>
<button type="button" onclick="testClosure()">Check Your Message</button>
<p id="sampleDemoOfClosure"></p>
<script>
function displayMessage (param1, param2) { var outerVariable = "Hi, ";
function prepareGreetings () {
return outerVariable + param1 + " " + param2;
}
return prepareGreetings ();
}
function testClosure() {
var message = displayMessage ("Good", "Morning"); document.getElementById("sampleDemoOfClosure").innerHTML = message;
}
</script>
</body>
</html>
Output:
The output is as follows after clicking “Check Your Message” button,
In the above code, prepareGreetings method can access the variable namely outerVariable of method displayMessage and parameters to displayMessage function namely param1 and param2 in its scope. Here, displayMessage is the outer method and prepareGreetings is the inner method.
Example #2
Global variables can be defined outside all the functions using var, let, or const, however, any variable which is not defined using var, let or const is global in javascript which can be present inside or outside the function and is accessible throughout the window scope. Unlike the local variables which have a lifespan of their function or block execution, the global variables have a lifespan until the page is discarded or the window is closed or we navigate to some other page. Let us check this out with the help of an example. Here we will modify the above program and add a global string and access it in the inner function.
Code:
<!DOCTYPE html>
<html>
<body>
<p>Demonstration of global variable in Javascript Closure</p>
<button type="button" onclick="testClosure()">Check Your Message</button>
<p id="sampleDemoOfClosure"></p>
<script>
var greeting="Have a great day ahead!"; function displayMessage (param1, param2) { var outerVariable = "Hi, ";
function prepareGreetings () {
return outerVariable + param1 + " " + param2+". "+greeting;
}
return prepareGreetings ();
}
function testClosure() {
var message = displayMessage ("Good", "Morning"); document.getElementById("sampleDemoOfClosure").innerHTML = message;
}
</script>
</body>
</html>
Output:
The output after clicking the buttons as follows,
Example #3
Closures or inner functions in javascript have access to its outer functions scope chain even after the outer function is returned.
Let us have a look at it with the help of an example.
Code:
<!DOCTYPE html>
<html>
<body>
<p>Demonstration of Javascript Closure after outer function is returned</p>
<button type="button" onclick="testClosure()">Get Today's Quote</button>
<p id="sampleDemoOfClosure"></p>
<script>
function getQuote (storiesStatement) {
var politicsStatement = "Politics always change.";
function prepareQuote (realityStatement) {
return politicsStatement + storiesStatement + " " + realityStatement;
}
return prepareQuote;
}
function testClosure() {
var todaysQuote = getQuote (" Stories"); var message = todaysQuote (" never do.");
document.getElementById("sampleDemoOfClosure").innerHTML = message;
}
</script>
</body>
</html>
Output:
The output after clicking “Get Today’s Quote” button is,
As can be seen, the getQuote function is the outer function that returns when the value (the inner function) is collected in todaysQuote variable. After that, the closure method i.e inner method prepareQuote is called using the collected variable todaysQuote which returns the quote which contains the outer function’s parameters and variables.
Example #4
Closures do not store the values of outer variables instead, it stores their references. Hence, outer variables can be changed even before the closure is called. This helps us to use the private variables in javascript.
We will see an example demonstrating the usage of private variables with the help of closures.
Code:
<!DOCTYPE html>
<html>
<body>
<p>Demonstration of using private variables with the help of javascript closures</p>
<button type="button" onclick="testClosure()">Get Employee Id</button>
<p id="sampleDemoOfClosure"></p>
<script>
function employeeId () { var employeeId = 1001;
return {
getEmployeeID: function () { alert("Employee Id is "+employeeId+".");
},
setEmployeeID: function (currentId) { employeeId = currentId;
}
}
}
function testClosure() {
var employeeNo1 = employeeId (); employeeNo1.getEmployeeID(); employeeNo1.setEmployeeID(1500); employeeNo1.getEmployeeID();
}
</script>
</body>
</html>
Output:
The output of the above code after clicking “Get Employee Id” button gives two alerts as shown,
The inner functions namely getEmployeeID() and setEmployeeID() help to retrieve and assign the current value to the employee id field. Firstly the employeeId is initialized with 1001 value and hence the first alert while retrieving value gives the message “Employee Id is 1001”.When inner method closure setEmployeeId is called with value 1500, the employeeId variable of outer function scope is changed and hence the second alert returns “Employee Id is 1500” message.
Closures Can Sometimes Lead to Bugs
As closures have access to the updated values of the outer function of the position where it is declared, it can lead to unexpected behavior especially while using for loops. These bugs occur because closures have access to the references of variables instead of their values. However, we can avoid such bug occurrences by using Immediately Invoked Function Expression (IIFE). Using immediately invoked function expressions to pass only the value of the variables or parameter instead of its references which solves the problem when using loops with closures.
Conclusion
In this way, we can use javascript closures to achieve data hiding, abstraction, and private variables which leads to encapsulation. Javascript Closures provide us with a great advantage of outer function variable accessibility and hence can be used extensively. However, you need to be careful while using them with loops such as for loops to avoid referential access and enable value access by using Immediately Invoked Function Expression along with closures.
Recommended Articles
This is a guide to JavaScript Closure. Here we discuss the introduction and top examples of JavaScript Closure along with code implementation. You may also look at the following articles to learn more-
- Javascript concat Method
- Arithmetic Operators in JavaScript
- Control Statement in JavaScript
- JavaScript Set Class
39 Online Courses | 24 Hands-on Projects | 230+ Hours | Verifiable Certificate of Completion
4.5
View Course
Related Courses