views:

241

answers:

7

My understanding of closures is that they are essentially a function which uses a variable that you would assume would be out of scope. I guess heres an example I saw the other day:

function closureMaker(somearg)
{
    var local_value = 7;
    function funcToReturn(arg1, arg2)
    {
        return local_value + somearg + arg1 + arg2;
    }
    return funcToReturn;
}
var myClosure = closureMaker(6);  //make the closure
myClosure(2, 3);                  //using it

Now the closure has local_value and even the original arg, somearg. But I dont get why these are helpful. What is the point of using the 'free' variable local_value or even more unknown to me, why would you use the argument of closureMaking function in your closure function?

I'm more interested in how this is used in javascript, Is this used a lot for AJAX requests and objects?

I got the what. I need the why.

A: 

This is probably not quite what you are looking for but there is an excellent talk about closures for Java (how they should/could be implemented) that also goes into some examples on where you would want to use them

http://www.youtube.com/watch?v=0zVizaCOhME

Matti
A: 

Closures are an easy way to make functions that depend on parameters. Or to put it another way, to create a specific instance of a family of functions (read on if that's not clear) depending on some run-time value.

Javascript lets you pass functions around as first-class members; so for example, you could pass around a function that determines how to combine two integers by referring to it directly.

However, going one step further, a closure lets you create a "customised" version of a function, whose exact behaviour depends on some runtime variable (but which otherwise conforms to a framework).

For example, here's a function that will allow a curried addition:

function getAddNFunction(n)
{
    function inner(operand)
    {
        return n + operand;
    }
    return inner;
}

Now if you call getAddNFunction(7), you get a function that adds 7 to an argument. If you call getAddNFunction(42.5), you get a function that adds 42.5 to the argument.

Hopefully this simple example clarifies the benefit of closures; they allow you to embed arguments in the function at creation time rather than them having to be passed in at execution time (after all, calling getAddNFunction(9)(2) is exactly the same as calling 9 + 2, except for the fact that the two arguments can be supplied at very different times).

So for instance you might want to return some kind of complex XML parsing function relative to some root element; a closure lets you embed that root element definition within the function itself, rather than depend on the caller having access to it whenever they want to execute the function.

Andrzej Doyle
+4  A: 

A common run-in is that in a for loop, you want to alert the number of the counter.

function addLinks () {
    for(var i = 0; i < 5; ++i) {
        var link = document.createElement('a');
        link.appendChild(document.createTextNode('Link ' + i));
        link.i = i;
        link.onclick = function() { alert( i ) };
        document.body.appendChild(link);
    }
}

addLinks();

When you go to click on these links, it will alert 5 because the loop has already been done and i is equal to 5. We didn't "save" the state of i at the time of execution of the for loop.

We can make a closure to "save" that state:

function addLinks () {
    for(var i = 0; i < 5; ++i) {
        var link = document.createElement('a');
        link.appendChild(document.createTextNode('Link ' + i));
        link.i = i;
        link.onclick = (function(i) { return function() {  alert(i ) } })(i);
        document.body.appendChild(link);
    }
}

addLinks();

The i is bound to the self executing anonymous functions invoked within each increment in our loop. This way the state is saved and we get the right # on alert.

meder
+4  A: 

The example you're looking at is trying to show you how closures work. I think of closures as little pieces of code that you can pass around. The neat thing is that (free) variables in the closure are bound based on the current lexical scope. This is why local_value keeps the value 7 because that's what the value of local_value was when the closure was created.

Javascript implements closures via anonymous functions*, but keep in mind that technically, these are two separate concepts.

In the context of Javascript, closures (implemented as anonymous functions) are very helpful when you want to deal with things that happen asynchronously; a good example is, like you stated, AJAX requests where you cannot predict when you will get a response back from a server. In this case, you have an anonymous function called a callback that you initially define and pass in when you make the AJAX call. When the call successfully completes, your callback is called to process the result. Closures result in cleaner code since you can package behavior and logic inside them. It also helps you abstract the behavior our and separate concerns.

Another use for anonymous functions/closures is for event handling. When an event happens your event handler is called.

Like I had mentioned before, you can abstract behavior and logic and put it in a closure. But what really makes a closure so powerful is context. You can customize the behavior of your closure, depending on the environment in which it was created. This makes your function very versatile, because you are defining its arguments (which will influence its behavior) while you are creating it, instead of when you are calling it (with explicit parameters) during execution.

Here is a good article about closures in Javascript. It's long, but informative:

* As CMS mentioned, named functions will behave like anonymous functions because they will have access to variables that are defined in the same lexical scope (or anything up the chain). This is most evident in inner functions. But if you think about it, the same happens for any function; you have access to variables that have been defined in the global scope (i.e., global variables).

Vivin Paliath
Just note that a *named function* will behave like an *anonymous* one, both having access to the upper levels of the scope chain (e.g. the function named `funcToReturn` on the OP's example).
CMS
@CMS thanks for that! yes, I've noticed that is the case in Javascript.
Vivin Paliath
+6  A: 

One of the most practical and widely spread usage of closures is to implement private or privileged members for example, for example:

function Test (param) {
  var secret = 3;
  function privateMethod() {
    //...
  }
  this.publicMember = param;
  this.privilegedMember = function () {
    return secret * param;
  };
}

var foo = new Test(10);
foo.privilegedMember(); // 30
foo.secret; // undefined

The module pattern is also a good example that can use the same principle, e.g.:

var myModule = (function () { 
  var obj = {}, privateVariable = 1; 

  function privateMethod() { 
    // ... 
  } 

  obj.publicProperty = 1; 
  obj.publicMethod = function () { 
    // private members available here... 
  }; 

  return obj; 
}());
CMS
A: 

If you are comnig from an OO world, closures allow you to create what are essentially private member variables, and methods, for your objects:

function Constructor(...) {
  var privateVar = value;
  function privateFunc() {
  }
  this.publicFunc = function() {
  // public func has access to privateVar and privateFunc, but code outside Constructor does not
  }
}

Douglas Crockford and javascript goodness

mlaw
A: 

In addition to above closure helps in hiding some of the implementation detail.

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 */

One more good article

Read this article on module pattern in javascript which heavily uses closures.

Zimbabao