Telerik blogs
JavaScriptT2 Light_1200x303

A closure is the combination of a function bundled together with references to its surrounding state. It’s a simple and useful technique once you understand it.

Closures are one of the most widely discussed and still confusing concepts in JavaScript—and also one of the most common questions you are likely to encounter in an interview when applying for a JavaScript position. As the title says, I will be making the topic clearer and easier to understand.

What Is a Closure?

A closure is a feature in JavaScript where an inner function has access to the scope (variables and parameters) of its outer functions, even after the outer function has returned.

Note: Scope in JavaScript refers to the current context of code, which determines the accessibility of variables to JavaScript. The two types of scope are local and global:

  • Global variables are those declared outside of a block
  • Local variables are those variables declared inside a block

In other words, a closure gives you access to the following scope:

  • Access to its scope; variables defined within its block of code
  • Access to the outer function’s variables
  • Access to the global variables

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

    // Defining the outer function.
    function enclosing() {
      var x = "outer";
      // Defining the inner function.
      function inner() {
        var y = "inner";
        console.log(x, y)
      }
      return inner;
    } 
    
    // invoking enclosing returns the inner function.
    var a = enclosing()
    a()

We defined two functions:

  • The outer function enclosing with a variable x that returns a nested function
  • The nested function inner with a variable y that logs both the value of its variable and that of its parent function

Note: A function can return another function in JavaScript. A function that is assigned to a variable is called function expression. And, the return statement does not execute the inner function—a function is executed only when followed by ()—but rather the return statement returns the entire body of the function.

This is a step-by-step walkthrough of the flow of execution:

  1. After invoking enclosing() at line 13, variable x is declared and assigned a value.
  2. Next is the declaration of the function inner.
  3. The return inner returns the entire body of the function inner.
  4. The contents returned by the return statement are stored in a. Thus, a will store the following:
    function inner() {
        var y = "inner";
        console.log(x, y)
    }
  1. Function outer() finishes execution, and all variables within the scope of outer() now no longer exist.

Note: The lifespan of a variable defined inside a function is the lifespan of the function execution.

What this means is that in console.log(x, y), the variable x exists only during the execution of the enclosing() function. Once the enclosing function has finished execution, the variable x no longer exists.

Now, we know that the function enclosing returns a function, and that gets stored in variable a.

  1. Since a is a function, we execute it on line 14. When we execute a(), we are essentially executing the inner function. Let us examine step-by-step what happens when a() is executed:

         a. Variable y is created and assigned a value.

         b. Next, it logs to the console the value of parent function variable x and its local variable y.

Now, you may be asking, “How does the function inner have access to its parent function variable x, since its parent function has finished execution long before we invoked a() and we noted earlier that the lifespan of a variable defined inside a function is the lifespan of the function execution?”

The answer to this question is …

Closures!

The function inner has access to the variables of the enclosing function due to closures in JavaScript. In other words, the function inner preserves the scope chain of function enclosing at the time it was executed, and thus can access the parent’s function variables.

The function inner had preserved the value of its parent function variable x when the parent function was executed and continued to preserve (closure) it.

It now refers to its scope chain and notices that it does have the value of variable x within its scope chain since it had enclosed the value of x within a closure at the point when the enclosing() function had executed.

Thus, that is how JavaScript can remember not only the value but also the variable of the parent function after it has long finished execution.

When to Use a Closure?

Closures are useful in hiding implementation details in JavaScript. In other words, it can be useful to create private variables or functions.

The following example shows how to create private functions and variables.

    var name = (function() {
        var username = "";
        function setName(val) {
          username = val;
          return username
        }
        return {
          set: function(val) {
            return setName(val);
          }
        };   
    })();
      
    console.log(name.set("John Doe"))

In the above example, set becomes a public function because it is included in the return object, whereas function setName becomes a private function because it is not returned and can only be used internally within the parent function.

Summary

Hopefully these step-by-step explanations helped you understand the concept of closures in JavaScript.


Chinedu
About the Author

Chinedu Imoh

Chinedu is a tech enthusiast focused on full-stack JavaScript and Infrastructure engineering.

Comments

Comments are disabled in preview mode.