After Immediately Invoked Function Expression, it's time for another very important topic.

Closures

At the moment, I hope that reading everything from the previous parts will pay off for a better understanding of what exactly is in JavaScript Closures.
At the start, let's write the often used, function hello once again, but instead of returning console.log, let's return the next function!

We see here something that thanks to the previous parts should be quite clear to notice.
Let's do this step by step.
We have a function hello with one paramter, say
Hello returns the next function, this time with the parameter name.
When the function hello is invoked in the seventh line, Syntax Parser, checking character by character knows that if we ended on hello ("Hello") we would just get the function code.
Then, we invoke the returned function and give it the "Tom" as an argument.
Thanks to that, we'll get "Hello Tom" in the console.

Now, let's change the code a bit.

As you can see, we've split the function invocation into two parts. To the variable hi, we save the invoked hello function with the argument "Hi". Next, as this is a function, we can invoke it with the argument "Joe".
Everything works as it should.

Now, however, let's think about one important stuff.
How does the JavaScript engine know when inwokes hi ("Joe") function, what is the argument stored in say. Wasn't it created in another Execution Context, and when all code from Execution Context is run, isn't it popped off the Execution Stack ?

From previous posts you could find out that each of the Execution Contexts contains its own space in memory for variables, functions.
And what happens to everything that is stored in memory when the Execution Context is removed from the stack?
Normally, the JavaScript engine, using the Garbage Collection, clears the memory.

Here, a very important thing happens. After executing the code in Execution Context, there is still a trace in memory to all variables we created there.
In our example, although the greeting variable can not be found in the function being returned, using the Scope Chain, the JavaScript engine looks for references. And although the hi function ended its life and was removed from the Execution Stack, it is possible to find the value of the say parameter in the place where it is allocated.

Closures is not something we create in the form of code. This is really a JavaScript engine feature.

Finally, I would like to show one example, which is very often found in tutorials that want to explain what the closures are.

What do you think we will get after invoking each function ?

Did anyone expect this? Or maybe you bet more on the result 1, 2 and 3? If you thought, however, it would be 1, 2 ,3,  I will try to break the function into small steps to better understand what Closure is.

  • In the above example, we have the function myFunction in which at the beginning we created an empty array and saved it in the arr variable (third line).
  • Then, using for loop, starting at 0, incrementing by 1, until the i variable is less than 3, we will execute the code.
  • This part of the code is nothing more than adding elements to the created array.
  • When i = 0, condition 0 < 3 is true, so we add the first element to our array using the push method. In our case, this is a function.

  • We increment by 1, now i = 1, and the rest of the code is executed until i < 3.
  • When the condition is no longer fulfilled, we will go out of for loor and as you can see in the fifteenth line, our main function will return arr array.
  • Then we save to the returned variable, the returned value from the myFunction function.
  • As these are functions in our array, we can invoke them using the parenthesis, as we do in lines 20, 21 and 22.

Now let's see how Execuion Contexts look.

  • At the beginning, a Global Execution Context is created which is hoisting myFunction.
  • After invoking the myFunction function, another Execution Context is created.
  • Inside it there are two things arr and i.

Now the main issue begins, which causes us to get three times 3.

  • We know that the variable is initially 0. The entire code in the loop is executed until the variable is 3 (not 2 !).
  • The loop will only end when the JavaScript engine sees that i = 3 no longer satisfy the condition (i = 3) <3.
  • In memory, the i value is saved, which is now 3.

Invoking every function stored in the array. The JavaScript engine starts looking for the i variable .


Although Execution Context of myFunction has already been removed from Execution Stack, as the entire code has already been executed. In the memory,  i = 3  has been saved, and the functions that has been pushed into the array have access to it.
 

So, as we now know that i variable always equals 3. The three returned values will be 3.

And what if I wanted it to work as "intended". What if we wanted 1,2,3 to be returend ?

ES6 let fixes that but I will talk about it soon.

Next Post

It will be about functional programming and it will be the last one before we get into ES6 features.