Closure in Javascript

Introduction

Today’s post is about closure. Let’s goooo!

Definition

Closure is a concept that refers to inner function that has access to the outer function. It can be a confusing concept without a review, so here it is!

Closure function is a function inside a function. As seen from the post on scope, the inner function can access variables in the outer function but the opposite cannot occur.

1
2
3
4
5
6
7
function makeFunc() {
  var name = "Mozilla";
  function displayName() {
    alert(name);
  }
  return displayName;
}

The above is an example from MDN. The function displayName is a closure function inside another function makeFunc. There are three scopes that could be accessed from displayName. The first is the function scope of itself, the second is the outer function scope of makeFunc and the last is the global scope that contains everything. The variable name can be accessed based on the rule of scope.

When makeFunc is called, it returns the function displayName, instead of calling it. So if we want to call displayName, we need to add one more bracket to makeFunc so it calls displayName after return. makeFunc()().

Now, when we assign makeFunc function to a variable, that variable now has displayName function.

1
2
3
let display = makeFunc(); 

// display returns displayName function. 

Therefore, when we call display(), displayName function is called.

One unique thing is that the variable that was defined in displayName (var name = “Mozilla”) is originally the local variable in the outer scope which should not be accessed when makeFunc fulfills its purpose. However, since Javascript saves the variable and function setting and forms it as displayName is returned, so the variable name can be used again. In closure function, local variable, variable in outer function and variables in global scope can all be accessed.

Application

Currying

Currying can be created using closure. Currying makes one function receives “n” number of functions instead of “n” number of parameters.

1
2
3
4
5
function adder (x) {
  return function (y) {
    return x + y;
  }
};

If we do adder(5), it will return a normal function and not return any number. However, if we do adder(5)(6) 5 is the parameter for x and 6 is the parameter of y and return 11.

To apply currying, assign adder to a variable.

1
let add5 = adder(5); 

Now, add5 returns a function with 5 as x. If we designate y’s value as something and call it, we can put a fixed value for x and calculate.

1
2
3
console.log( add5(3) )

// 8 is the result. 

Private Method

Next, we will try to create a private method using a closure module pattern. There is no private concept in Javascript.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var counter = (function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  };   
})

Using an object, we set increment, decrement and value as key and its value as an application of inner function to change the variable privateCounter using changeBy.

If we return counter, it returns an object that contains increment, decrement and value. Since counter contains a function that returns an object, if counter.increment() is called, the function inside increment is called, if counter.decrement() is called, the function inside decrement is called and if counter.value() is called, the function inside value is called. increment and decrement change the value of privateCounter using the function changeBy and counter.value() returns privateCounter.

If we want to distinugish different counts using currying, assign counter() to different variables.

1
2
3
4

let count1 = counter();

let count2 = counter();

If we apply currying as above and call count1.increment() and count2.decrement(), the values will not be related to each other because each hold privateCounter “privately”.

End of Closure!

0%