Closure in JS

Closures are functions that refer to independent (free) variables . In other words, the function defined in the closure ‘remembers’ the environment in which it was created. (or) Inner function "closes over" the variables it references, preserving their values.

Example 1

Inner function accessing outer function's scope

You can easily guess this code

function outerFunction() {
   let a = 10;

   function innerFunction() {
      console.log('a is: ', a);
   }
   innerFunction() // 2nd innerFunction Calls
}
outerFunction(); // 1st outerFunction Calls
Console

a is: 10

Modified code for explaining the Closure

Accessing the values in outerFn, even after its execution finished - Because of "Closure"

You can easily guess this code

function outerFn() {
   let a = 20;

   return function innerFn() {
      console.log('a is: ', a);
   }
}

const returnedVal = outerFn(); 
//outerFn returns innerFn
//And the assignment operator stores the returned function in a variable. 

returnedVal(); //Call the returned function using that variable name.
Console

a is: 20

Explanation:

After the outerFn() execution finished, it will be removed from the Callstack memory.

The returned function is execution start after the outerFn() execution finished only.

Now how did the returned function got the value of a, which present in the finished outerFn ?

Well, In JavaScript, when a function is defined within another function, it forms a closure.

A closure allows the inner function to access the variables of the outer function, even after the outer function has finished executing.

This is because the inner function "closes over" the variables it references, preserving their values.

Example 2

See how this code runs

(I recommend to check step by step in debugger mode)

for(let a = 0; a < 5; a++) {
    setTimeout(function(){
        console.log(a);
    }, 1000);
}

Now put below consoles, (just to see the execution order in output)

console.log('Script Started');

for(let a = 0; a < 5; a++) {
    setTimeout(function(){
        console.log(a);
    }, 1000);

    console.log("loop " + a + " Ended" )
}

console.log('Script Ended');
Console

Script Started
loop 1 Ended
loop 2 Ended
loop 3 Ended
loop 4 Ended
loop 5 Ended
Script Ended
0
1
2
3
4

Explanation:

setTimeout() is an Asynchronous function. So it will run after all Synchronous code are finished

Here setTimeout ran after the for loop finished. But how it got the 'a' variable which existed during each particular loop? Well, here is what Closure happens.

My Golden Words:

Take your time to learn Closure.

Practice Closure concept in different scenarios or in different design patterns

It took years for me to get better clarity in Closures, on learning by myself. But you can learn sooner from other developer's experience. "Read, listen, share and Practice a lot"