Our blog, keeping you up-to-date on our latest news.

 

Javascript Notes: Closure

March 17, 2011 at 6:53 am | Blog | 1 comment

 

Recently, I am reading some articles and posts on javascript closure, which is an advanced topic in Javascript. And it is not easy to get it. But understanding it is essential to mastering the language. I made some notes on closure, and have a much clearer picture on closure and its usage. I would like to share the notes with all, and if there is some misunderstanding, please help me to improve.

Note 1:

“Whenever you see the function keyword within another function, the inner function has access to variables in the outer function.”


closure happens in the codes with an inner function. or more generally,

“a closure is a function defined within another scope that has access to all the variables within the outer scope.”

So, this is like a precondition for Closure.

Note 2:

“A closure is when you return the inner function. The inner function will close-over the variables of the outer function (scope) before leaving.”

For example, the following code snippet:

function foo(x) {
  var tmp = 3;
  function bar(y) {
    alert(x + y + (++tmp));
  }
  bar(10);
}
foo(2)

the inner function bar can access the variables x and tmp, from the outer function foo. but the inner function is only working in the foo scope, so there is no closure actually.

Now, let’s see another example:

function foo(x) {
  var tmp = 3;
  return function (y) {
    alert(x + y + (++tmp));
  }
}
var bar = foo(2); // bar is now a closure.
bar(10);

compared to the first example, in this example the inner function is returned, so the out side world can call the inner function where ever you want to. And the function bar can still refer to x and tmp, even though it is no longer directly inside the scope. Now That’s a typical Closure.

Since tmp is still hanging around inside bar’s closure, it is also being incremented. It will be incremented each time you call bar.

So why closure is useful? First of all, “Encapsulation”. Make some data private, not visible to the outside world. don’t let the other code to modify it. For example, the variable tmp is not accessible out side foo without the closure. But when you call “bar”, the tmp is still manipulated each time.

Readers who have experience of OO programing language may ask, why not defining a class to encapsulate the private data? Yes, you are absolutely right! So there is another usage of closure is in call back functions, which is more convenient than OO design. see the following example for more details.

Note 3:

specifying a method of an object as the callback function will cause the function by itself to be the callback, not the object associated with it.

This sentence may be not easy to understand at the first place, but if you check out the examples bellow, you will know what it is talking about.

Consider the following class, it uses a classical constructor with function prototypes to work like a class from other languages.

// Define the constructor
function Person(name, age) {
  // Store the message in internal state
  this.message = name + ", who is " + age + " years old, says hi!";
};
Person.prototype.greet = function greet() {
  console.log(this.message);
};
};
 
var bob = new Person("Bob", 47);
bob.greet();

Nice clean OO code right? The good thing is that you get to write your methods outside of the constructor instead of nested inside it. This is a very comfortable pattern and is used by a lot of successful JavaScript projects

But with closure, we can write it in another way without using new and prototype:

// Define the factory
function newPerson(name, age) {
  // Store the message in a closure
  var message = name + ", who is " + age + " years old, says hi!";
  return {
    greet: function greet() {
      console.log(message);
    }
 
  };
}
var tim = newPerson("Tim", 28);
 
tim.greet();

a factory function newPerson that creates a closure and exposes parts of it as public methods. Externally it looks a lot like the class based version, but internally it’s 100% a closure and there isn’t a this or new in sight. It is clean and easy to read. One word of caution though. While this method is quite easy to use, it doesn’t perform well when you’re creating large numbers of instances, as each instance will create its own version of every function in the object. Not like prototype in the class definition, which only creates one copy of function.

But as i mentioned, Closures for events and callbacks is where closures are the most useful. see the following code snippet:

var bob = new Person("Bob", 47);
var tim = newPerson("Tim", 28);
 
setTimeout(bob.greet, 100);
// Outputs: undefined
 
setTimeout(tim.greet, 100);
// Outputs: Tim, who is 28 years old, says hi!

the first call:

setTimeout(bob.greet, 100);

out puts undefined.This is because specifying a method of an object as the callback function will cause the function by itself to be the callback, not the object associated with it.

Variables from the closure, however are part of the function itself, no matter how it’s called.

See the difference?

I hope, these notes will help you understand javascript, and Closure better.

Reference:
Why user “Closure” from Tim Caswell
How do JavaScript closures work?

<< Back to Blog Discuss this post

 

One Comment to “Javascript Notes: Closure”

  1. Cordelia says:

    BION I’m iprmsesed! Cool post!