DEV Community

Bikash Mishra
Bikash Mishra

Posted on

Closure in JavaScript

Coding in JavaScript without an understanding of closures is like trying to speak English without an understanding of grammar rules — you might be able to get your ideas across, but probably a bit awkwardly.

Closure is one of important concepts in JavaScript. It is widely discussed and still confused concept. Let's understand what the closure is.

What are Closures?

As stated in MDN Web Docs, a closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time.

What is Lexical Scope?

Lexical scope is the ability for a function scope to access variables from the parent scope. We call the child function to be lexically bound by that of the parent function.

A Simple closure

Let’s look at a simple closure example in JavaScript:

function OuterFunction() {

    var outerVariable = 1;

    function InnerFunction() {
        alert(outerVariable);
    }

    InnerFunction();
}
Enter fullscreen mode Exit fullscreen mode

In the above example, InnerFunction() can access outerVariable.

Now, InnerFunction() can access outerVariable even if it will be executed separately. Consider the following example.

function OuterFunction() {

    var outerVariable = 100;

    function InnerFunction() {
        alert(outerVariable);
    }

    return InnerFunction;
}
var innerFunc = OuterFunction();

innerFunc(); // 100
Enter fullscreen mode Exit fullscreen mode

In the above example, return InnerFunction; returns InnerFunction from OuterFunction when you call OuterFunction(). A variable innerFunc reference the InnerFunction() only, not the OuterFunction(). So now, when you call innerFunc(), it can still access outerVariable which is declared in OuterFunction(). This is called Closure.

Above example also shows that the local variables are not copied in the closure: the closure maintains a reference to the original variables themselves. It is as though the stack-frame stays alive in memory even after the outer function exits.

Closure Scope Chain

Every closure has three scopes:

  • Local Scope (Own scope)
  • Outer Functions Scope
  • Global Scope

When to use Closure?

Closures are useful whenever you need a private state associated with a function. This is a very common scenario - and remember: JavaScript did not have a class syntax until 2015, and it still does not have a private field syntax. Closures meet this need.

Performance considerations

It is unwise to unnecessarily create functions within other functions if closures are not needed for a particular task, as it will negatively affect script performance both in terms of processing speed and memory consumption.

Final points:

  • Whenever a function is declared in JavaScript closure is created.
  • Returning a function from inside another function is the classic example of closure, because the state inside the outer function is implicitly available to the returned inner function, even after the outer function has completed execution.
  • A closure in JavaScript is like keeping a reference (NOT a copy) to the scope at the point of function declaration, which in turn keeps a reference to its outer scope, and so on, all the way to the global object at the top of the scope chain.
  • A new set of local variables is created every time a function is called.

I hope this helps someone out there.

If you liked this post, you can find more by:

Tweet this post
Follow me on Twitter @forkbikash

Latest comments (2)

Collapse
 
artydev profile image
artydev

Thank you for your post

Closures in callback are perfect use case :

import {button, div} from "./dml"; /* <sdtio.h> :-) */

function Counter () {
    let count = 0;
    let value = div("0");
    button("inc").onclick = () => value.innerText = ++count;
    button("dec").onclick = () => value.innerText = --count;
}

Counter();


Enter fullscreen mode Exit fullscreen mode

You can test it here : Counter

Collapse
 
forkbikash profile image
Bikash Mishra

Yeah! absolutely.
Thanks for your appreciation @artydev .