What Is a Closure in JavaScript ?

What Is a Closure in JavaScript ?

In JavaScript, closure is a combination of functions bundled together with the reference to its surrounding state that is the lexical environment. It means that closure gives you access to the outer function scope rather than an inner function scope. When the function gets created, the closure also gets created.

Before going to closure, let's first see what is lexical scoping?

See the following example to understand the lexical scoping:

function displayName()

{

    var name = "html5awesome";

   function showName()

{

   alert(name);

}

   showName();

}

  displayName();

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.

When you run this code in the JavaScript script you will get the alert message window with the value stored in the name variable & that value is a "html5awesome".

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?

Take a look at the following code, to understand the JavaScript Closure

function displayName()

{

     var name = "html5awesome";

    function showName()

{

   alert(name);

}

return showName;

}

var fun1 = displayName();

fun1();

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.

You might be questioning how is it possible? because a variable declared within the function body has scope within that function body only, it might not be accessible after the complete execution of the code. But your code is still working as expected, which means that it is possible in JavaScript.

It is possible just because of the JavaScript Closure. We already have seen that the JavaScript closure is nothing but a combination of function & the lexical environment in which that function has declared.

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.

As we all know JavaScript is a front-end web language. So, when we define an object in JavaScript it is related to an event which is nothing but a click event or mouse event triggered by the user.

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 -

body{

color: red;

font-size : 12px;

}

h1 {

font-size : 1.5em;

}

h2 {

font-size : 1.2em

}

The script to run the above code is

function sizer(size)

{

return function()

{

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

Global 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;

function sum(p){

return function(q){

return function(r){

return function(s){

return p+q+r+s+i;

}

}

}

}

console.log(sum (2)(5)(3)(6));

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.

Why use Closure in JavaScript?

JavaScript Closures are used to enable data privacy. When you use closure for data privacy, then enclosed variables are only in scope within the nested function.

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.

You've successfully subscribed to HTML5Awesome
Great! Next, complete checkout to get full access to all premium content.
Welcome back! You've successfully signed in.
Unable to sign you in. Please try again.
Success! Your account is fully activated, you now have access to all content.
Error! Stripe checkout failed.
Success! Your billing info is updated.
Billing info update failed.