Closures.

Closures.

How not to learn closures :)

LETS DIVE INTO THE WORLD OF CLOSURES.

Topics covered in this blog: Scope, Scope chain and nesting, Closures, Advantages and disadvantages of closures.

First of all, for learning/understanding closures, we should have a deep understanding of how javascript handles scopes and how it evaluates any block or function's parent scope. Let's see a example:

 let a = 10;
 let b = 10;

 (function mult() {
     let ans = a * b;
     console.log(ans);
  })(a, b);

IMP: The function written above is called as IIFE(immediately invoked function expression)

Read about iife here

With this example, we can see that it's simply multiplying two numbers but because of hoisting(When you write some code, javascript first goes through your code and puts all the variables(var, let, const) and functions at the top of your code and puts undefined in it just like a placeholder) in the global execution context(let's say global scope) where all the global scoped variables are stored as undefined at the start and functions are stored literally as it is. This was all just for starting, now when we come to the function, firstly it creates it's own Execution context where all its local variables are assigned to undefined, we can see that it first creates a let ans variable which basically does all the multiplication but when it comes to performing the operation, function mult() looks for variables a and b in its own scope and then it goes to its lexical parent(Global scope). So, basically lexical scope means access to its parent execution context or rather i say the parent's local variables. Got it, if not let's dig deep.
Now, let's understand with the help of nested scopes.

function outer() {
  let a = 10;
  function inner() {
    console.log(a);
  }
  inner();
}

outer(); // it logs 10

So, it seems that the inner function has it's own scope(execution context) which we can call as inner scope and outer function has it's own scope (outer scope). So, the inner function first looks for a variable in its local or inner scope then if it doesn't find, it will look to its parent(outer) scope also known as it's lexical scope and will then log the value 10.

Now, finally let's see where closures come into picture. By modifying just a little bit of the previous code,

function outer() {
  let a = 10;
  function inner() {
    console.log(a);
  }
  return inner;
}
/* This just stores the
whole inner function in it */
const ans = outer();

ans();

/You can also write the above functions like this/

function outer() {
  let a = 10;
  return function inner() {
    console.log(a);
  }
const ans=outer();
ans();

}

So as we can see here, we have just added a return keyword to the inner function and we have captured the inner function in a variable ans later in the code. Now, the magic that happens is when javascript engine runs the outer function and makes a variable a and assign it to 10 and then just returns the inner function (Note: We are just returning the inner function not calling it) The ans variable now contains the inner function and what if we call it, will it work? Will the inner function be able to log 10 in the console or it will be a reference error of ans not defined. Let's see,

Screenshot 2021-11-14 at 9.02.08 AM.png It logs 10 to the console but why? I was out of my mind when i first read about it but let me explain, When inner function gets called outside of the outer function, which means there should not any variable available to the inner function as the outer function has done its job but that's where closures come, the inner function remembers the variable ans or rather the variable ans is enclosed with the inner function. This is what we call as closures, Basically,Closures are nothing but function bind together with its lexical scope or parent scope. There are many closures applications which makes it one of the most important topic in JavaScript.

USES OF CLOSURES:

1) setTimeouts.
2) currying.
3) memoize.
4) To maintain state in async.

Advantages of closures:
1) most callbacks are dependent on how closures work.
2)Mostly used in Encapsulation of the code.
3) Also used in creating API calling wrapper methods.
Disadvantages of closures:
1) Variables used by closure will not be garbage collected.
2) If closures will not be handled correctly it will result to memory leaks.

Excellent video for understanding Closures, Click here