Sunday 28 August 2016

JavaScript Closure

To understand Closure we have to understand Scope. So first we discuss about Scope then slowly move to Closure.

Scope is a programming language controls for the visibility and lifetimes of variables and parameters.
var foo = function ( ) {

 var a = 3, b = 5;

 var bar = function ( ) {

  var b = 7, c = 11;
  // At this point, a is 3, b is 7, and c is 11

  a += b + c;
  // At this point, a is 21, b is 7, and c is 11
 };

 // At this point, a is 3, b is 5, and c is not defined

 bar();

 // At this point, a is 21, b is 5
};
  Most languages with C syntax have block scope. All variables defined in a block (a list of statements wrapped with curly braces) are not visible from outside of the block. This is a good thing. Unfortunately, JavaScript does not have block scope. JavaScript does have function scope. That means the parameters and variables defined in a function are not visible outside of the function, and that a variable defined anywhere within a function is visible everywhere within the function.

  In many modern languages, it is recommended that variables be declared as late as possible, at the first point of use. That turns out to be bad advice for JavaScript because it lacks block scope. So instead, it is best to declare all of the variables used in a function at the top of the function body.
var myObject = function ( ) {
 var value = 0;
 return {
  increment: function (inc) {
   value += typeof inc === 'number' ? inc : 1;
  },
  getValue: function ( ) {
   return value;
  }
 };
}();
We are not assigning a function to myObject. We are assigning the result of invoking that function. Notice the () on the last line. The function returns an object containing two methods, and those methods continue to enjoy the privilege of access to the value variable.
/*Create a maker function called quo. It makes an object with a 
get_status method and a private status property.*/
var quo = function (status) {
 return {
  get_status: function ( ) {
   return status;
  }
 };
};

// Make an instance of quo.
var myQuo = quo("amazed");
document.writeln(myQuo.get_status());
When we call quo, it returns a new object containing a get_status method. A reference to that object is stored in myQuo. The get_status method still has privileged access to quo’s status property even though quo has already returned.
get_status does not have access to a copy of the parameter; it has access to the parameter itself. This is possible because the function has access to the context in which it was created. This is called closure.

Let’s look at a more useful example : Example - 1 :
var add = (function () {
 var counter = 0;
 return function () {
  return counter += 1;
 }
})();

add();
add();
add();
The variable add is assigned the return value of a self invoking function. The self-invoking function only runs once. It sets the counter to zero (0), and returns a function expression.

Example - 2 :
// Define a function that sets a DOM node's color to yellow and then fades it to white.
var fade = function (node) {
 var level = 1;
 var step = function ( ) {
  var hex = level.toString(16);
  node.style.backgroundColor = '#FFFF' + hex + hex;
  if (level < 15) {
   level += 1;
   setTimeout(step, 100);
  }
 };

 step();
};

fade(document.body);
We call fade, passing it document.body (the node created by the HTML <body> tag). fade() sets level to 1. It defines a step function. It calls step function. It then returns fade has finished.
So we can say, "A closure is a function having access to the parent scope, even after the parent function has closed".

3 comments: