When to Use Closures?

A closure is useful in hiding implementation detail in JavaScript. In other words, it can be useful to create private variables or functions – closure is valid in multiple levels of inner functions.

The following example shows how to create private functions & variable:

Example 1
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

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


Closures vs. Global Scope

Closures are like creating global variables in the global scope and a function that accesses them, but then enclosing this whole environment inside of a function.

Example 1: Closure is similar to the global scope
var passed = 3;

var addTo = function () {
    var inner = 2;
    return passed + inner;
};

console.dir(addTo());

As you can see, function addTo is a normal top level function, and it has access to an outer variable passed – a global variable. Consequently, addTo is a function declared inside a scope – in this case, the global scope – similar to a closures.

Example 2: User closures instead of globals

// Trying to solve the global variable usage issue using a one-level function doesn't work.
let global1 = function (newval) {
  let num = 0;

  if (newval) {
    num = newval;
  }
  return num;
}

global1();   // 0
global1(5);  // 5
global1();   // 0 again; that's not useful..


// Using a two-level function (i.e. Closure) helps get the variable re-definition issue out of the scope.
const makeGlobalVar = function () {
  let num = 0;

  return function (newval) {
    if (newval) num = newval;
    return num;
  }
}

const num2 = makeGlobalVar();

num2();  // 0
num2(5); // 5
num2();  // 5 still.

num2(5) is the equivalent of assigning a value to a global variable, (i.e. this num2 = 5).
And num2() is the equivalent of getting the value of a global variable (i.e. this num2).

The gist that you need to get from all of this, is that a closure is good for protecting values from conflict and unintended change. Thus, closures are used in distributing JavaScript modules and libraries – each library uses closures to prevent variable conflicts.