boy-Over-9
== write & share ==

Understand JavaScript Closures with basic examples

February 11, 2023

Definition

In JavaScript, a closure is a function that has access to variables in its outer scope, even after the outer function has returned. This means that the closure can “remember” the values of the variables in its enclosing scope, even if those variables are no longer in scope. The closure is a combination of the function and its associated reference environment, which is the set of variables that are accessible from the function.

Here’s a simple example of a closure in JavaScript:

function outerFunction(x) {
  return function innerFunction(y) {
    return x + y;
  };
}

const addWith5 = outerFunction(5);
console.log(addWith5(3)); // 8

In this example, the outerFunction returns the innerFunction, which has access to the x variable in its outer scope. The addWith5 variable is assigned the result of calling outerFunction with an argument of 5, so the innerFunction has access to the x variable with a value of 5. When we later call addWith5(3), the innerFunction is executed with a value of y equal to 3, and it returns the sum of x and y, which is 8.

Closures are often used in JavaScript for things like creating private variables and methods, or for preserving state across multiple function calls. They provide a way to create a “protected” environment for a function to operate in, allowing it to access and modify variables that would otherwise be inaccessible.

Applications examples 1:

for(var i = 0; i < 5; i++) {
    setTimeout(function() { console.log(i); }, i * 1000 );
}
// output: 5 5 5 5 5

How to use closure to fix bug in this funtion?

Solution

The issue is that the value of i is not “captured” by each iteration of the for loop, so by the time the setTimeout function is executed, i has already been incremented to its final value of 5.

Here’s an example of how you can use a closure to capture the value of i for each iteration of the loop:

for (var i = 0; i < 5; i++) {
  (function (j) {
    setTimeout(function () { console.log(j); }, j * 1000);
  })(i);
}

In this example, we wrap the setTimeout function in an anonymous immediately invoked function expression (IIFE), which takes j as an argument. The value of j is passed as i when the IIFE is invoked, so each iteration of the loop creates a new closure with its own j variable that is “captured” by the inner function. When the setTimeout function is executed, it has access to the correct value of j for each iteration, so it logs the expected values of 0, 1, 2, 3, and 4.

The second application example: private variables and methods

Closures can be used to create private variables and methods in JavaScript.

Here’s an example to demonstrate this concept:

function Person(firstName, lastName) {
    let privateFullName = firstName + " " + lastName;
  
    return {
        getFullName: function() {
            return privateFullName;
        }
    };
}

let person = Person("Alex", "Lee");
console.log(person.getFullName()); // outputs "Alex Lee"

Conclusion

Closure is a powerful feature of JavaScript that allows you to create private variables and methods, or to preserve state across multiple function calls. It’s also a useful tool for creating “protected” environments for functions to operate in, allowing them to access and modify variables that would otherwise be inaccessible.


Profile picture

written by boy-Over-9
Eat, sleep, code, Judo repeat... Twitter