Closures in Javascript.

According to Mozilla Developer Network:
Closures are functions that refer to independent (free) variables. In other words, the function defined in the closure ‘remembers’ the environment in which it was created.

Another short description:
Whenever you see the function keyword within another function, the inner function has access to variables in the outer function.
That is a closure, man.

Let’s look at the simple example

function testClosure(){
  var x = 4;
  function getX(){
    return x;
  }
  return getX;
}

Then, let’s try to call testClosurefunction.

var test = testClosure();
test(); //4

When we call testClosure() we assign the getX function to a variable test. So we can just do console.log(test) and see this

function getX(){
  return x;
}

Then we can call it as a function, since the variable stores a function expression.

Practical closures

Practically, we can use closures in order to create similar functions efficiently. Consider we have following code that represents players from the teams:

function getTeam(teamName) {
    return function getPlayer(playerName) {
        console.log("Team: " + teamName + "; Player:" + playerName);
    }
}

var houston = getTeam("Houston");
houston("Harden"); // outputs Team: Houston; Player:Harden

var chicago = getTeam("Rose");
chicago("Rose"); // outputs Team: Houston; Player:Rose

Also a closure lets you associate some data with a function that operates on that data.

Another example. Consider that we want to add some buttons that adjust the text size.Our interactive text size buttons can change the font-size property of the body element, and the adjustments will be picked up by other elements on the page thanks to the relative units.

function makeSizer(size) {
  return function() {
    document.body.style.fontSize = size + 'px';
  };
}

var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);

size12, size14, and size16 are now functions which will resize the body text to 12, 14, and 16 pixels, respectively. We can attach them to buttons (in this case links) as follows:

document.getElementById('size-12').onclick = size12;
document.getElementById('size-14').onclick = size14;
document.getElementById('size-16').onclick = size16;
<a href="#" id="size-12">12</a>
<a href="#" id="size-14">14</a>
<a href="#" id="size-16">16</a>

Emulating private methods with closures

JavaScript does not provide a native way of doing this, but it is possible to emulate private methods using closures. Private methods aren’t just useful for restricting access to code: they also provide a powerful way of managing your global namespace, keeping non-essential methods from cluttering up the public interface to your code.

Here’s how to define some public functions that can access private functions and variables, using closures which is also known as the module pattern:

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()); /* Alerts 0 */
counter.increment();
counter.increment();
alert(counter.value()); /* Alerts 2 */
counter.decrement();
alert(counter.value()); /* Alerts 1 */

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.

For instance, when creating a new object/class, methods should normally be associated to the object’s prototype rather than defined into the object constructor. The reason is that whenever the constructor is called, the methods would get reassigned (that is, for every object creation).

Consider the following impractical but demonstrative case:

function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
  this.getName = function() {
    return this.name;
  };

  this.getMessage = function() {
    return this.message;
  };
}
function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
}
MyObject.prototype = {
  getName: function() {
    return this.name;
  },
  getMessage: function() {
    return this.message;
  }
};

In previous example the inherited prototype can be shared by all objects and the method definitions need not occur at every object creation.

Used resource:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

Share this post:Tweet about this on TwitterShare on Facebook0Share on LinkedIn0Share on Google+0Share on Reddit0Email this to someoneDigg this