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?
What is a closure?
As defined on MDN:
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.
How do we return a function from another function?
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.
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.
Calling a function outside of the function call, in which it was defined-
Note:Where we define our functions, determines what variables our functions have access to when we call the function.
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!!