Opening up about Closures

Opening up about Closures

Closure is one of the most key concepts and most confusing concepts of Javascript, at least to me it is. If you understand it properly, it could unlock some new superpowers for you in Javascript. So let's demystify this mystery of closure.

The Definition

The MDN doc says "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 is an inner function that has access to the outer function's variable in addition to it's own variables and the global variables. The inner function has access not only to the outer function's variables but also to the outer function's parameters. Closures are created everytime a function is created.

Let's decode this one by one.

Lexical environment

It's a vast concept in itself, but for the time being think of Lexical environment as an object associated with every function, block scope (anything inside {}) and even the whole script itself. It contains two parts

  • Environment Record – an object that stores all local variables as its properties.
  • A reference to the outer lexical environment, the one associated with the outer code.

So, whenever a new function or a block scope is created, a new lexical environment is created along with it and since the new function/Block has access to the Lexical environment of its outer function/Block, it can access all the properties (variables & parameters) of the outer function.

Let's understand it with an example

function closureExample(){
   var i = 0;

   for(i=0; i<3 ; i++){
     setTimeout(()=>{
           console.log('counter value is '+i);
      },1000)
   }
}

Here:

  • variable i exists in the scope of of the function closureExample
  • since the function console.log is passed as a callback to the setTimeout function, it is not immediately executed.

  • the console.log will be executed asynchronously 3 times, and only after each timeout of 1 second elapses.

  • This means that 3 timeouts are set and then the closureExample returns almost immediately.

  • Ultimately the line counter value is 3 is printed 3 times after 1 second elapses and the function has returned.

  • This suggests that the callback function still had access to the variable i even after the function closureExample had returned.

how is this possible?

That's the beauty of Closures.

When the logging function is passed to the setTimeout method, the Javascript engine detects that for the function to be executed in the future, a reference will be needed to variable i.

To solve this, the engine keeps a link to this variable for later use, and stores that link in a special function scoped execution context.

Such a function with 'memory' about the environment where it was created is simply known as: a Closure.

But why was the output showing the value of i as 3 only?

It happened because the logging function is a closure containing a reference to the variable i, note that its a reference and not a copy, so it happens like this:

  • the loop finishes and the variable i has a value of 3 now.
  • the function is returned and the callstack gets empty, so all the setTimeout functions would be executed after 1 second.

  • Since all those functions have a reference to the variable i (which has a value of 3 now), would log the value 3.

In a Nutshell

  • The concept of Closure says that functions/blocks inside another function/block have the access to the properties ( variables & parameters ) of the bigger scopes.

  • Whenever a function/block is created, a new Lexical Environment is created and associated with it.

  • The function inside another function has access to its parent's properties even after the parent function has returned.

Thank you for reading.