Closure

Closure

Closure is an important concept in JavaScript and often asked in technical interviews.

What is Closure?

According to MDN, a closure is a combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In short, a closure gives you access to an outer function's scope from an inner function.

For understanding closures better let's first understand what is lexical scope.

Lexical Scope

Lexical scope means that in a nested group of functions, the inner functions have access to the variables and other resources of their parent scope.

This means that the child's functions are lexically bound to the execution context of their parents.

Lexical scope is sometimes also referred to as static scope. The diagram below outlines the supposed hierarchy that the lexical scope maintains in JavaScript. diagram

Let's Look at an Example:

function parenFunc(){
    let lastName = "Musk";
    function childFunc(params) {
        console.log(`Hi! My name is Elon ${lastName}.`);
    }
    childFunc();
}

parenFunc();

Here parenFunc() creates a local variable called lastName and a function called childFunc(). The childFunc() function is an inner function that has no local variables of its own. However, since inner functions have access to the variables of outer functions, childFunc() can access the variable lastName declared in the parent function, parenFunc().

Remember the child function has the access to the variables of parent function but Parent function cannot access the variables of child function. Example

function parenFunc(){
    let lastName = "Musk";
    console.log(firstName);
    function childFunc(params) {
        let firstName = "Elon";
        console.log(`Hi! My name is ${firstName + " " + lastName}.`);
    }
    childFunc();
}

parenFunc();

Output image.png

In the above example we get ReferenceError on accessing the firstName in the parentFunc().

Closure

Example:

function parenFunc(){
    let lastName = "Musk";
    function childFunc(params) {
        let firstName = "Elon";
        console.log(`Hi! My name is ${firstName + " " + lastName}.`);
    }
    return childFunc;
}

var myFunc = parenFunc();
myFunc();

Output: image.png In the above example, we are returning inner Function i.e. childFunc() from the outer function i.e. parenFunc(). But the thing to note here is we don't get an error even though we are only returning the inner function that is accessing a variable which is declared in the outside function.

So, here is an interesting thing about functions in JavaScript. Functions, when returned from another function, maintain their lexical scope or in simple terms they remember where they were actually present.

This is the reason why we don't get an error.