My FeedDiscussionsHeadless CMS
New
Sign in
Log inSign up
Learn more about Hashnode Headless CMSHashnode Headless CMS
Collaborate seamlessly with Hashnode Headless CMS for Enterprise.
Upgrade ✨Learn more

Closures - JavaScript

Pankaj Wadhwani's photo
Pankaj Wadhwani
·May 28, 2021·

4 min read

Hello Reader! In this blog, you will learn about one of the most important concepts of JavaScript that is closure. So let's get started and understand what closure is.

What is Closure?

A closure is the combination of a function and the lexical environment within which that function was declared. In other words, it simply means that an inner function always has access to the variables and parameters of its outer function, even after the outer function has returned. Let's have a look at an example.

// Closure Example
function parentFunction(){
    let parentFunctionVariable="parent"
    function innerFunction(){
        let innerVariable="inner";
        console.log("parent function variable is : ",parentFunctionVariable);
        console.log("inner variable is : ",innerVariable);
    }
    return innerFunction;
}
const newFunction = parentFunction();
newFunction();

/* output is: 
    parent function variable is :  parent
    inner variable is :  inner */

In the above code, when we first call the parentFunction , we set parentFunctionVariable as parent, and then we have the innerFunction which gets returned and assigned to newFunction. Then as we call the newFunction, it logs the parentFunctionVariable as well as the innerVariable.

Let's see if we can access parentFunctionVariable after the function gets returned or not:

function parentFunction(){
    let parentFunctionVariable="parent"
    function innerFunction(){
        let innerVariable="inner";
        console.log("parent function variable is : ",parentFunctionVariable);
        console.log("inner variable is : ",innerVariable);
    }
    return innerFunction;
}
const newFunction = parentFunction();
console.log(parentFunctionVariable);
//Uncaught ReferenceError: parentFunctionVariable is not defined at index.js:14

Oops, we can not access it here but newFunction is able to access parentFunctionVariable because of Closure. newFunction consists of an innerFunction that comes with the scope of the parentFunction (i.e. Lexical Environment) which together bundled is called Closure.

One important characteristic of closure is that the inner function doesn't just take the values of the parent function variables instead it stores the reference of the variables. And anytime the inner function is run it actually accesses the current live value of variables. Refer to the example below:

function counter(){
    let count=0;
    function add(){
        return count+=1
    }
    return add;
}

const increment = counter();

console.log("count is : ",increment()); //count is : 1
console.log("count is : ",increment()); //count is : 2

In the above example, when the increment is called first, it takes the value of count i.e. 0 and increases it by one. Then increment is called again. Now it takes the value 1 from the reference of the count variable which is the current live value of count instead of 0, increases it by 1, and outputs the value of count as 2.

Note: Closure is also valid in multiple levels of inner functions.

Now you know what closure is and also understand how it works. So the next question comes when to use closure or what can you use it for?

Uses of Closures.

  • creating separate state

Closures can be used to create a state which can be accessed during each function call. We can also do this by creating a variable globally as they are accessible throughout the program. But the drawback will be that the global variables can be changed anywhere in the code. So closures help us in maintaining the state between function calls without using a global variable. We have practically seen this above in a code where we used a count variable in a state and accessed it multiple times during each call. This use can also be referred to as using private variables and methods.

  • function factories

One powerful use of closures is to use the outer function as a factory for creating functions that are somehow related. Suppose we want to create three functions to change the font size to 12,14 and 16 pixels. Instead of creating three separate functions, we will use closures to do so. Refer to example below to see how it's done.

function makeSizer(size) {
  return function() {
    document.body.style.fontSize = size + 'px';
  };
}

var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);

In the above code, we used makeSizer as a template to create three different functions size12, size14, and size16 using closures.

I hope this blog helped you. Thank you for reading.

Keep Learning. Keep Growing.