Closures in JavaScript

mariaverse

CiaraMaria

Posted on October 5, 2020

Closures in JavaScript

Closures are one of those concepts that a lot of new developers seem to have trouble with. Myself being one of them. In this post, I will attempt to make this mystery-shrouded concept a little less mysterious by addressing the point I initially missed when learning closures: persistence of data.

Here is the official definition of Closures according to MDN: "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."

Closures in JS have three main traits:

  • A function must return another function
  • The inner function has access to variables from the outer function
  • Variable value from the outer function is persisted

Let's look at an example closure:

function parentFunc() {
    var counter = 0;

    function childFunc(){
      let innerCounter = 0;
      innerCounter++;
      counter++;
      console.log(counter, innerCounter);
    }

    return childFunc;
}

const myChild = parentFunc();
myChild();
Enter fullscreen mode Exit fullscreen mode

In the snippet above, we have a function called parentFunc() which returns it's nested function childFunc(). parentFunc() has a var counter set to 0. childFunc() has a var innerCounter set to 0, it increments both counter and innerCounter, then logs both. We set const myChild equal to the executed parentFunc().

The output is for the above code is:

1 1
Enter fullscreen mode Exit fullscreen mode

Pretty straightforward, right?
What if we execute myChild() more than once?

function parentFunc() {
    var counter = 0;

    function childFunc(){
      let innerCounter = 0;
      innerCounter++;
      counter++;
      console.log(counter, innerCounter);
    }

    return childFunc;
}

const myChild = parentFunc();
myChild();
myChild();
myChild();
Enter fullscreen mode Exit fullscreen mode

The output is now:

1 1
2 1
3 1
Enter fullscreen mode Exit fullscreen mode

In regular functions, once the function is executed it is wiped clean and does not persist any data.
When using closures, however, the inner function stores variables from the outer function in its own special location, which we can think of like a backpack. The outer function executes and data within it is wiped clean, but the inner function has that data stored in its backpack which it can reach into and grab. Note that it is only storing the variable from the parentFunc() in the backpack, it's own variable innerCounter gets treated as a regular function and wiped clean after execution.

childFunc() persists the value for var counter as it is when the function completes. Meaning that at the start of the second execution var counter is not set to 0, it is set to 1 and at the start of the third execution var counter is set to 2.

This makes the use of closures a great option when we want to remember certain values in functions.

Conclusion

Closures in JS have three main traits:

  • A function must return another function
  • The inner function has access to variables from the outer function
  • Variable value from the outer function is persisted

Closures are subtle concepts in JavaScript that can be difficult at first. But once you break them down and understand the three main traits, you may realize that they don't have to be so controversial.

Hopefully, this post helped you better understand the concept of closures in JavaScript!

đź’– đź’Ş đź™… đźš©
mariaverse
CiaraMaria

Posted on October 5, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Closures in JavaScript
javascript Closures in JavaScript

October 5, 2020