Closure is a fundamental JavaScript concept that every programmer ought to know about!

WHY??

It gives our functions persistent memories.. Let’s find out how!

Having said that, it is quite natural that the internet is laden with explanations that are all priceless in one way or the other.

I personally find it easier to wrap my head around a concept when I get some visual explanation about what the tool is, and how it is making my code more efficient.

I will provide some code snippets to give us some room for imagination. So, let’s dive right into it, shall we?

Hmm…

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.

The functions in JavaScript form closures. A closure is the combination of a function in the lexical environment within which that function was declared. This environment consists of any local variables that were in-scope at the time the closure was created.

Note:The entire JavaScript file is one scope, and the function is another scope.

Let’s take a look at a code for example:

When we run the function with the input of 3, the input of 3 is absolutely forgotten the next time we run the function with the input of 10. So, when the function is run inside of it, we get a store of data. The next time the function is run with a different input, we get a brand new data, and therefore, there is no connection between these two functions being run.

Normally, when our functions get run, we create a live store of data inside of them, which, there is a local memory for that function running. So, when we run the function with the input of 3 and get 6, the 3 (input) gets deleted and the only thing that is held onto is the returned output of 6.

When JavaScript goes through the code line by line, it stores data in the memory like such: when it sees the keyword function, it stores this function or the code for later. The function essentially has two parts: the name of the function and totally separate from it, the stored code of the function.

In the first line, the function is being declared and JavaScript is storing that in the global memory. In line two, we are creating a const diffLabel to the global memory and it will be assigned the function definition of createFunction.

We saved the function and it’s label in one block and we have a new label for the same function code in the second line of code. We have two labels for the same function code.

In line three, we do not store anything in generatedFunction until we run createFunction and see what the output is, and that output is what that gets stored in generatedFunction.

When we run a function, we create an execution context, and when we execute a function, e.g createFunction, it needs two things: a mini memory of all the stuff that gets created and then it is going to go through the code line by line, this is known as thread, and if it needs to store something, it is going to be stored in the local memory.

Hence, the first thing that gets stored inside createFunction is the label, multiplyBy2 and assigned to the function definition of multiplyBy2. Next we are going to return multiplyBy2 and it will get stored in generatedFunction. The reason being, when JavaScript sees the keyword return, it goes to look for the label and grabs the function definition and return it out into the label, generatedFunction. This was previously labeled as multiplyBy2 and JavaScript used its label to find its definition. And now it exits this execution context and hits the next line.

In the next line, we declare the label result which is equal to the output of invoked function generatedFunction. In other words, run createFunction and see what gets returned. It returns the whole function definition of multiplyBy2, returns it out and stores it in generatedFunction. Thus, generatedFunction has nothing to do with createFunction after that line.

The thing about JavaScript is that, when we declared the label generatedFunction, we can then put a function in it and then run that function by the label by putting () parentheses in the end. This is exactly what we do in the next line, we declare result, and we put () in the end of generatedFunction and JavaScript goes to see what generatedFunction is and finds the function formerly known as multiplyBy2. So then we create , what is known as execution context, which is just a mini app to run the function and we use the code of multiplyBy2 to run it. That is how we ran createFunction and stored its result in generatedFunction. Therefore the takeaway here is that nothing gets stored in generatedFunction unless we run createFunction and what gets returned from it, will get stored in generatedFunction.

Note:Where we define our functions, determines what variables our functions have access to when we call the function.

The above code is working similarly to it’s previous example, so in line one, the label outer is getting saved in the global memory along with the function definition. In the next line Javascript is creating a new execution context with a local memory to run outer, it will set a variable there, counter and assign it the value of 0. Next, it stores the function definition of incrementCounter, and returns out the definition of incrementCounter. The output of outer is going to be stored in the global label, myNewFunction. Thus, the functionality that was previously known as incrementCounter is now, myNewFunction. And it exits out of this execution context.

Now, as Javascript hits the next line, myNewFunction(), it creates a new execution context here and it is going to run the function definition of incrementCounter within the global memory, and not inside of outer. It looks for the definition of myNewFunction in the local memory first and next in the global.

So we ran outer and returned out incrementCounter, and now incrementCounter is running by its new name myNewFunction, which has counter++ in, yet JavaScript cannot go back in outer, as outer’s memory has diminished, the question remains, how will it still have access to the functionality of outer.

Here’s what happens, when we returned out incrementCounter into myNewFunction, we brought more than just the function definition, we brought all the surrounding local memory that was attached on to the function. So, when the function came out, it grabbed the data along with it in the backpack, as some would refer to it, and stored it in the new global label, myNewFunction. So, now when it hits the next line of myNewFunction(), it creates another execution context, does not find anything in the local memory, so it looks into the data that the function definition has attached to it. In other words, it looks in the backpack, and finds counter which is 1 and it now increments it to 2. We basically have access to permanent data attached to the function, in this case myNewFunction. One important take away is that this backpack of data is not in the global memory and it is only available upon running the function that the data is attached to. This is how we no longer have to hold data in global memory for it to be permanent . We would not have to pollute global memory with names or labels, so instead the data we want to hold on to, we put it in function’s backpack.

Note: Counter is not in the global memory. It is bundled up and protected inside of myNewFunction as a label.

** Execution context is a concept to evaluate the runtime of the code. At any given time, there can only be one execution context executing code.

** Every execution context has a Lexical Environment that holds variables and their associated values, and also has a reference to its outer environment.

** The set of identifiers that each environment has access to is called scope. Scope essentially means, what data is available to us at any given with our function when we run it.

I really hope this was somewhat helpful. This concept is fairly new to me and I would really appreciate any feedback on this topic.

Happy Coding y’all!!

Software Engineer | Day Dreamer | Get Better by the Day