Closure

May 20, 2023

In JavaScript, a closure is a function that has access to variables in its outer lexical scope, even after the outer function has returned. In other words, a closure allows a function to remember and access variables from the scope in which it was created, even if that scope is no longer active.

The concept of closures is often difficult for new JavaScript developers to understand, but it is an important concept to grasp as it is a common pattern used in many JavaScript programs.

Purpose

Closures are used to provide encapsulation and to create private variables in JavaScript. By using closures, you can create functions that have access to private variables, which cannot be accessed or modified from outside the function.

Closures are also used to create functions that can generate other functions. This is often used in functional programming and is known as currying. By creating a function that returns another function, you can pass different arguments to the returned function to create different variations of the original function.

Usage

To create a closure in JavaScript, you need to define a function inside another function. The inner function will have access to the variables in the outer function, even after the outer function has returned.

Here is an example of a closure:

function outer() {
  var x = 10;

  function inner() {
    console.log(x);
  }

  return inner;
}

var closure = outer();
closure(); // Output: 10

In this example, the outer function returns the inner function. When the outer function is called, it defines a variable x with a value of 10. It then defines the inner function, which has access to the variable x. Finally, it returns the inner function.

When the outer function is called, it returns the inner function. This returned function is assigned to the variable closure. When the closure function is called, it outputs the value of the variable x, which is 10.

The closure function has access to the variable x even though it was defined in the outer function, which has already returned. This is because the inner function is a closure and has access to the variables in the scope in which it was created.

Private Variables

Closures are often used to create private variables in JavaScript. Private variables are variables that can only be accessed and modified from within the function in which they were defined.

Here is an example of a closure that creates a private variable:

function counter() {
  var count = 0;

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

var increment = counter();
increment(); // Output: 1
increment(); // Output: 2
increment(); // Output: 3

In this example, the counter function defines a variable count with a value of 0. It then returns an anonymous function that increments the count variable and outputs its value.

When the counter function is called, it returns the anonymous function. This returned function is assigned to the variable increment. When the increment function is called, it outputs the value of the count variable, which is incremented by one each time the function is called.

The count variable is a private variable because it can only be accessed and modified from within the counter function. The increment function has access to the count variable because it is a closure and has access to the variables in the scope in which it was created.

Currying

Closures are also used to create functions that can generate other functions. This is known as currying and is a common pattern used in functional programming.

Here is an example of a closure that creates a curried function:

function add(x) {
  return function(y) {
    return x + y;
  }
}

var addTen = add(10);
console.log(addTen(5)); // Output: 15
console.log(addTen(10)); // Output: 20

In this example, the add function takes a parameter x and returns an anonymous function that takes a parameter y. The anonymous function returns the sum of x and y.

When the add function is called with a value of 10, it returns the anonymous function. This returned function is assigned to the variable addTen. When the addTen function is called with a value of 5, it returns the sum of 10 and 5, which is 15. When it is called with a value of 10, it returns the sum of 10 and 10, which is 20.

By using closures to create curried functions, you can create functions that can be reused with different arguments to create variations of the original function.