What is Closures?

A closure is the combination of a function bundled together with references to its the lexical environment. In other words, A Closure is nothing but a function inside another function. This closure function can access the variables inside its own scope, the outer function's variables and the global variables.

What is Lexical scoping

When a function is defined in another function, the inner function has access to the outer function’s variables. This behavior is called lexical scoping.

Example of Closure:-

function outerFunc() {
  // the outer scope
  let outerVar = 'Hello World';

  function innerFunc() {
    // the inner scope
    console.log(outerVar); // 'Hello World'
  }

  return innerFunc;
}

const inner = outerFunc();
inner();

Output:

Hello World

Explanation: In the above example, the outer function outerFunc creates a variable outerVar, which is then being used inside the inner function innerFunc. Within the inner function, there is no variable declared, but due to closure, it can access the variable declared within the outer function.

What is Scope

A scope in JavaScript defines what variables you have access to. There are two kinds of scope – global scope and local scope.

Closure Scopes :-closure has three scopes:

  • Local Scope

  • Outer Functions Scope

  • Global Scope

Let see understand through example

// global scope
var scoreVar = 5;
function sum(scoreOne){
  return function(scoreTwo){
    return function(scoreThree){
      // outer functions scope
      return function(scoreFour){
        // local scope
        return scoreOne + scoreTwo + scoreThree + scoreFour + scoreVar;
      }
    }
  }
}

console.log(sum(20)(10)(30)(60)); // Ouput 125

JavaScript closures in a loop

for (var i = 1; i <= 3; i++) {
    setTimeout(function () {
        console.log('after ' + i + ' second(s):' + i);
    }, i * 1000);
}

Output

after 4 second(s):4
after 4 second(s):4
after 4 second(s):4

The code shows the same message.

What we wanted to do in the loop is to copy the value of i in each iteration at the time of iteration to display a message after 1, 2, and 3 seconds.

The reason you see the same message after 4 seconds is that the callback passed to the setTimeout() a closure. It remembers the value of i from the last iteration of the loop, which is 4.

In addition, all three closures created by the for-loop share the same global scope access the same value of i.

To fix this issue, you need to create a new closure scope in each iteration of the loop.

There are two popular solutions: IIFE & let keyword.

What is the practical use for a closure in JavaScript?

allows for the nesting of functions and grants the inner function full access to all the variables and functions defined inside the outer function (and all other variables and functions that the outer function has access to). A closure is a code block with bound variables - it "catches" its variables from their outer context - but it is independent from that same context. A practical use in javascript is when defining events or callbacks - you declare a closure to be executed on the click of a button, for instance, but this closure can reference variables declared on the caller scope.

Benefit of Closure

The benefit of Closure is to preserve local variables within the scope Maintain state between each function call.

Why Closures?

Now that we’ve cleared that up, let’s cover the why. Why would you want to care about closures? Granted, closures make a lot of sense in the functional programming world, after all, you need functions to be first-class citizens in order to have closures. So if you’re going full OOP with your JavaScript code, you’re probably not interested or even see the need for such a concept. And that is perfectly fine, but mind you, JavaScript is not a completely OOP language, even though ES6 has tried to bridge that gap by adding concepts, such as classes. So, let me show you some benefits of mixing things up a bit and I’ll let you decide then, if closures are for you or not.