DEV Community

francesco agati
francesco agati

Posted on

Introduction to Functional Programming in JavaScript: Closure #2

Closures are a fundamental concept in JavaScript that every developer should understand. They play a crucial role in functional programming and are essential for creating more advanced functionality in JavaScript applications.

What is a Closure?

A closure is a function that has access to its own scope, the scope of the outer function, and the global scope. This means that a closure can access variables and parameters from its own function scope, the scope of the function that contains it, and any global variables.

In other words, a closure allows a function to "remember" the environment in which it was created, even after the outer function has finished executing.

How Closures Work

To understand how closures work, let's look at a simple example:

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

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

    return innerFunction;
}

const myClosure = outerFunction();
myClosure(); // Output: 'I am from the outer function'
Enter fullscreen mode Exit fullscreen mode

In this example:

  • outerFunction creates a variable outerVariable and defines innerFunction, which accesses outerVariable.
  • innerFunction is returned from outerFunction and assigned to myClosure.
  • When myClosure is called, it still has access to outerVariable from outerFunction's scope, even though outerFunction has already finished executing.

This ability of the innerFunction to access the variables from the outer function's scope after the outer function has completed execution is what defines a closure.

Practical Uses of Closures

Closures have many practical applications in JavaScript. Let's explore a few common use cases:

  1. Data Encapsulation
    Closures can be used to create private variables that cannot be accessed directly from outside the function.

    function createCounter() {
        let count = 0;
    
        return {
            increment: function() {
                count++;
                return count;
            },
            decrement: function() {
                count--;
                return count;
            }
        };
    }
    
    const counter = createCounter();
    console.log(counter.increment()); // 1
    console.log(counter.increment()); // 2
    console.log(counter.decrement()); // 1
    

    In this example, count is encapsulated within the closure created by createCounter, making it inaccessible from the outside.

  2. Function Factories
    Closures can be used to create functions dynamically based on input parameters.

    function createMultiplier(multiplier) {
        return function(number) {
            return number * multiplier;
        };
    }
    
    const double = createMultiplier(2);
    const triple = createMultiplier(3);
    
    console.log(double(5)); // 10
    console.log(triple(5)); // 15
    

    Here, createMultiplier returns a new function that multiplies its input by a specified multiplier. Each created function maintains its own multiplier value through closures.

  3. Callbacks and Event Handlers
    Closures are often used in asynchronous programming, such as with callbacks and event handlers.

    function fetchData(url) {
        return function(callback) {
            // Simulate an asynchronous operation
            setTimeout(() => {
                const data = `Data from ${url}`;
                callback(data);
            }, 1000);
        };
    }
    
    const fetchFromAPI = fetchData('https://api.example.com');
    fetchFromAPI((data) => {
        console.log(data); // Output after 1 second: 'Data from https://api.example.com'
    });
    

    In this example, fetchData returns a function that accepts a callback. This callback has access to the url variable even after the delay, demonstrating the power of closures in asynchronous code.

Top comments (1)

Collapse
 
jonrandy profile image
Jon Randy 🎖️

A closure is a function that has access to its own scope, the scope of the outer function, and the global scope.

This definition is not correct. A closure is not a function, and ALL functions have access to their surrounding scope.