In working with JavaScript, at a certain point, a lot of the architecture in your project will revolve around working with instances. This can range from mutation state to simple initialization. Knowing that let’s take a deeper look at that context in dealing with functions. What if you wanted a way to contain scope and instance together without having a reactionary effect from a change on the outside. In functions within JS, to accomplish this we would use closures!

Approaching A Closure

Simply put, a closure can be broken down like this:

  • A closure is created by a function instance and returned to its target
  • It contains a reference to the instance scope of the parent function that created it
  • It creates an internal instance scope on every function call of the created closure

That may seem like a lot to understand at first, but in essence, it’s really a cumulation of the information from previous articles. Breaking each main point down individually, you’ll see that.

Creating A Closure

The first point in our breakdown briefly put the creation of a closure into context. Creating closure takes calling a function that returns another function. This may sound similar to creating a new object/class instance in JS from looking at that creation process. However, there are striking differences that make them different concepts and better for different use cases.

In a class or object creation sense, the return is the this of the new instance from the generator function being called. The primary scope itself is that of the instance returned and stays that way throughout its lifespan in your application.

A closure similarly is created the same way, but the function used to create it does not return this. The returned value is a function definition that is assigned to its target with a reference to that instance of the generator function called as its parent scope. Like any function, a closure’s internal scope changes every time its called(JS instance).

Using A Closure

Now that we understand the concept of how and why of creating a closure, let’s look at a use case example.

So let’s say you have some logic in your code base that requires two separate method calls to get your desired end result. As a quick example, let’s think of a method where you pass in a number and return the value of that number when added to an already predefined number.

function addToBase(base) {
  return function(num) {
    return base + num;
  }
}

Looking at this you might be thinking that this same logic could be easily reworked to use a defined variable in the accessible parent scope. While that would be a possible alternative, but what about the case where you want to use a different base value in different situations.

To properly access it using the parent scope would require constant monitoring to ensure the correct value is being read. In our closure example, that isn’t the case. The returned method has proper access to it from the parent scope that was used to create it.

In Closing

Closure’s seem great right! They give us great flexibility in terms of properly scaling and structuring our codebases. While this example was very simple, the possibilities that it exposes to you show an enormous amount of possibilities. So the next time you’re writing some logic out in your codebase, and take time to consider if a closure is the better option at that time.