DEV Community

Cover image for How do JavaScript closures work?
Neeraj Kumar
Neeraj Kumar

Posted on

How do JavaScript closures work?

Closure means that an inner function always has access to the vars and parameters of its outer function, even after the outer function has returned.

You have learned that we can create nested functions in JavaScript. Inner function can access variables and parameters of an outer function (however, cannot access arguments object of outer function)

function OuterFunction() {

    var outerVariable = 1;

    function InnerFunction() {
        alert(outerVariable);
    }

    InnerFunction();
}

Enter fullscreen mode Exit fullscreen mode

example, InnerFunction() can access outerVariable.

Now, as per the definition above, InnerFunction() can access outerVariable even if it will be executed separately.

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.

A function can return another function in JavaScript. A function which is assigned to a variable is called function expression.

function Counter() {
    var counter = 0;

    function IncreaseCounter() {
        return counter += 1;
    };

    return IncreaseCounter;
}

var counter = Counter();
alert(counter()); // 1
alert(counter()); // 2
alert(counter()); // 3
alert(counter()); // 4
Enter fullscreen mode Exit fullscreen mode

outer function Counter returns the reference of inner function IncreaseCounter(). IncreaseCounter increases the outer variable counter to one. So calling inner function multiple time will increase the counter to one each time.

function Counter() {

    var counter = 0;

    setTimeout( function () {
        var innerCounter = 0;
        counter += 1;
        alert("counter = " + counter);

        setTimeout( function () {
            counter += 1;
            innerCounter += 1;
            alert("counter = " + counter + ", innerCounter = " + innerCounter)
        }, 500);

    }, 1000);
};

Counter();
Enter fullscreen mode Exit fullscreen mode

if inner function access the variables of outer function then only it is called closure.

When to use Closure?
Closure is useful in hiding implementation detail in JavaScript. In other words, it can be useful to create private variables or functions.

var counter = (function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  };   
})();

alert(counter.value()); // 0
counter.increment();
counter.increment();
alert(counter.value()); // 2
counter.decrement();
alert(counter.value()); // 1
Enter fullscreen mode Exit fullscreen mode

increment(), decrement() and value() becomes public function because they are included in the return object, whereas changeBy() function becomes private function because it is not returned and only used internally by increment() and decrement().

Top comments (0)