DEV Community

gaurbprajapati
gaurbprajapati

Posted on

Closure in javascript Complete concept

In JavaScript, a closure is a combination of a function and the lexical environment in which that function was declared. It allows the function to access variables from its outer scope even after the outer function has finished executing.

To understand closures better, let's look at an example:

function outerFunction() {
  var outerVariable = 'I am from the outer function';

  function innerFunction() {
    console.log(outerVariable);
  }

  return innerFunction;
}

var closure = outerFunction();
closure(); // Output: I am from the outer function
Enter fullscreen mode Exit fullscreen mode

In this example, outerFunction is the outer function that contains innerFunction. Inside innerFunction, we are accessing the outerVariable from the outer scope of outerFunction. Even though outerFunction has finished executing and its execution context is gone, innerFunction still has access to the outerVariable. This is possible because of the closure.

Closures are created when an inner function is defined inside an outer function and the inner function is returned or passed as a reference to another function or stored in a variable. In our example, we return innerFunction from outerFunction and assign it to the closure variable. The returned innerFunction still retains access to the variables of its outer scope, forming a closure.

Few more examples to understand closures in JavaScript:

Example 1: Counter Function

function createCounter() {
  let count = 0;

  return function() {
    count++;
    console.log(count);
  };
}

const counter = createCounter();
counter(); // Output: 1
counter(); // Output: 2
counter(); // Output: 3
Enter fullscreen mode Exit fullscreen mode

In this example, the createCounter function creates a closure. It declares a count variable and returns an inner function. The inner function has access to the count variable from its outer scope. Each time the inner function is invoked, it increments the count and logs the updated value to the console. The output shows how the inner function, due to the closure, can access and modify the count variable even after the createCounter function has finished executing.

Example 2: Private Variable

function createPerson(name) {
  let privateName = name;

  return {
    getName: function() {
      return privateName;
    },
    setName: function(newName) {
      privateName = newName;
    }
  };
}

const person = createPerson('John');
console.log(person.getName()); // Output: John
person.setName('Jane');
console.log(person.getName()); // Output: Jane
Enter fullscreen mode Exit fullscreen mode

In this example, the createPerson function creates a closure that encapsulates a private variable privateName. It returns an object with two methods: getName and setName. The getName method accesses and returns the private privateName, while the setName method modifies the private variable. The closure ensures that the privateName variable is not accessible from outside the createPerson function, providing data privacy.

Example 3: Emulating Private Methods

var Counter = (function() {
  let count = 0;

  function increment() {
    count++;
    console.log(count);
  }

  function decrement() {
    count--;
    console.log(count);
  }

  return {
    increment: increment,
    decrement: decrement
  };
})();

Counter.increment(); // Output: 1
Counter.increment(); // Output: 2
Counter.decrement(); // Output: 1
Enter fullscreen mode Exit fullscreen mode

In this example, an immediately invoked function expression (IIFE) is used to create a closure. The IIFE defines private variables count and private functions increment and decrement. It returns an object with the public methods increment and decrement. The closure allows the public methods to access and modify the private count variable, while keeping it hidden from the global scope.

These examples demonstrate different use cases of closures in JavaScript, such as maintaining private variables, creating function factories, and encapsulating data. Closures provide a powerful mechanism for achieving data privacy and creating modular and reusable code.

Closures are useful in many scenarios, including:

Data Privacy:
Closures can be used to create private variables and functions. By encapsulating variables within an outer function and exposing only necessary functionality through inner functions, you can control access to data and provide a level of privacy.

Function Factories:
Closures allow you to create functions dynamically with different configurations. By defining an outer function that takes certain parameters and returns an inner function, you can create specialized functions tailored to specific needs.

Callbacks:
Closures are often used with callbacks to capture and maintain the state of variables. The inner function, being a closure, retains access to the variables from the outer scope, even when the callback is invoked later.

Top comments (0)