Closures are a concept that puzzle many JavaScript developers, even after reading the zillion articles that have been written about the topic. Yes, this is just one of those zillion articles šŸ˜„, but Iā€™ll do my best to explain it.

To explain what a closure is, first we have to explain the concept of scope.

The scope indicates in which places a given variable is available. Global variables (i.e. those not inside a function or block) are available everywhere in the code.

If you create a new variable inside a function, the scope of that variable is the function itself, itā€™s not available outside. And if you create one function inside another, the inner function can access the parentā€™s variables.

And if you create a variable using const and let inside a block of code enclosed in curly braces ({ and }), those variables exist inside that block only.

In JavaScript, functions can return another functions. When that happens, the new function can access the variable from its parent. For example:

function createLuckyNumberFunction(name) {
    const luckyNumber = parseInt(10000 * Math.random());

    return function() {
        return `${name}'s lucky number is ${luckyNumber}`;
    }
}

const mikesLuckyNumber = createLuckyNumberFunction("Mike");
console.log(mikesLuckyNumber());
// šŸ‘† Outputs "Mike's lucky number is 3220"

const juliasLuckyNumber = createLuckyNumberFunction("Julia");
console.log(juliasLuckyNumber());
// šŸ‘† Outputs "Julia's lucky number is 1449"

The function createLuckyNumberFunction (from now on, Iā€™ll call it the ā€œparent functionā€) create another function (the ā€œchild functionā€) and returns it.

The child function can access the variables from the parent, with the values they had when the child function was created.

For example, the function that we get from the first call to createLuckyNumberFunction has access to the variables name = "Mike" and luckyNumber = 3220. And the function from the second call can read the following variables: name = "Julia" and luckyNumber = 1449.

A closure is a combination between a function and its surrounding variables. In this example, the closures are made of the inner function and the variables name and luckyNumber.

Closures are useful when you want to hide variables and prevent them from being modified externally. In the examples above, nobody can change the lucky number after it was created.

Another use is when the function will be executed in a different context (i.e. as a callback), but the function needs variables that may not be available at call time.