What are the use cases for closures/callback functions in JavaScript? - javascript

I was listening to Crockford's talk on JavaScript closures and am convinced of the benefit of information hiding, but I do not have a firm understanding of when to use callback functions.
It is mostly a true statement that a person could accomplish the same functionality with or without callbacks.
As someone who is writing code, what heuristics or cues should I keep in mind when determining when to use callbacks/closures?
I am not looking for the blanket statement 'Closures make more secure code', rather a list of practical examples or rules of thumb for when callbacks are the right idea.
Crockford's Presentation:
http://www.yuiblog.com/blog/2010/04/08/video-crockonjs-5/

Firstly:
Callback: A function passed as an argument to another function, usually to be called as a result of an event occurring.
Closure: A retained scope. I.e. the concept that when you declare a function within another function, the outer function's scope is accessible within the inner function.
Callbacks can also be closures but are not always.
This is a callback:
someProcess(myCallback);
function myCallback() {
alert('Done...');
}
function someProcess(callback) {
// does stuff...
// ...
callback();
}
A closure:
function foo(msg) {
function bar() {
// I can access foo's scope
// (i.e. bar can access everything that foo can access)
alert(msg);
}
return bar;
}
foo('hello')(); // alerts "hello"
One common usage of closures is to provide information-hiding, which is helpful in bringing some kind of encapsulation to the language. Have a look at the module pattern to see this in action.
Another common usage is when the binding event handlers to elements. E.g.
var myElements = [ /* DOM Collection */ ];
for (var i = 0; i < 100; ++i) {
myElements[i].onclick = function() {
alert( 'You clicked on: ' + i );
};
}
That wouldn't work. By the time the element is clicked, the variable i is 99. To make this work properly we could use a closure to capture the value of i:
function getHandler(n) {
return function() {
alert( 'You clicked on: ' + n );
};
}
for (var i = 0; i < 100; ++i) {
myElements[i].onclick = getHandler(i);
}

Let's say you want a function that you can use to return a unique "id" value to use when you create new DOM elements. Now, in something like Java, you could create a class with an internal private counter, and then have a method that appends the counter to some prefix string. Well, in Javascript:
var getId = (function() {
var counter = 0;
return function() {
return "prefix" + counter++;
};
})();
Now the variable "getId" is bound to a function that's created by another function, and created in such a way that it has a persistent variable to use between invocations. Similarly, if I wanted to have a family of "getId" functions (say, one for each type of DOM element I might add), I could do this:
var getIdFunc = function(prefix) {
var counter = 0;
return function() {
return prefix + counter++;
};
};
var getId = {
'div': getIdFunc('div'),
'span': getIdFunc('span'),
'dl': getIdFunc('dl'),
// ...
};
Now I can call getId.div() to get a new "id" value for a new <div>. The function was created by calling a function that provides two values stashed away in a closure: the prefix string (passed in as an argument) and the counter (a var declared in the closure scope).
Once you get used to it, the facility is so flexible and useful that you'll feel pain at moving back to an environment without it.
Oh, and here's a tip to help keep you off StackOverflow should you try this out: it's an issue that pops up all the time:
for (var i = 0; i < 10; ++i) {
var id = "foo" + i;
var element = document.getElementById(id);
element.onclick = function() {
alert("hello from element " + i);
};
}
What's the problem here? Well, that "i" variable that's referenced by that function is the "i" from the scope in which that loop runs. That variable, you'll note, gets incremented through the loop (duhh, right?). Well, every single one of those little functions created and assigned as event handlers will share that same, single variable "i" in the closure scope. Oops! The solution is to do something like this:
for (var i = 0; i < 10; ++i) {
var id = "foo" + i;
var element = document.getElementById(id);
element.onclick = (function(iCopy) {
return function() {
alert("hello from element " + iCopy);
};
})(i);
}
We make a copy of the outer "i" into a closure scope of its own, so now each event handler has its own!
To summarize: the technique of leveraging closures comes up all the freaking time once you get used to it. It's not a free ticket into a new wonderland of error-free programming; don't get me wrong. It is, however, a very useful and flexible paradigm.

This writeup from Mozilla may answer why use closures and when
Also, see this set of examples (especially "What can be done with Closures?" section that has the following exmples):
Example 1: setTimeout with Function References
Example 2: Associating Functions with Object Instance Methods
Example 3: Encapsulating Related Functionality
I have e feeling that this can be traced to Crockford, but the classic use of closures is to emulate private instance or static variables (which JavaScipt lacks)

Related

Proper way to handle scope in JavaScript

I have code that schematically follows the pattern below. The significant part is that there's a parameter declared in the outer function that is later used in the inner one.
function outer(){
var parameter = 3;
this.value = parameter;
$("#something").on("click", function(target){
target.value = parameter / 2;
});
}
In reality, the inner functions are quite a few and rather lengthy so I was hoping to move them out in order to improve readability, like so.
var parameter = 3;
function outer(){
this.value = parameter;
$("#something").on("click", inner);
}
function inner(target){
target.value = parameter / 2;
}
However, what I noticed is that, because of the scoping paradigm of JavaScript, I had to move out the parameter declaration out of the outer function, hence making it global, which to me seems like a disadvantage. (In reality, there are many parameters being used so passing them directly defeats the purpose.)
I can't decide which approach is less flawed. The question is if it's OK to pollute the global scope in order to gain readability or if it's an absolute no-no.
Re your revised question:
The question is if it's OK to pollute the global scope in order to gain readability or if it's an absolute no-no.
It's an absolute no-no. The global namespace is already far, far too polluted. And there's almost never any reason to do it: Instead, you can pollute use a scope that contains all of your code (near-global, if you will) as much as you want:
(function() {
// Our private scope
var lots, of, vars, here;
function outer() {
// ...
}
function inner() {
// ...
}
})();
That at least keeps your variables from truly being globals.
It's still best, though, to keep the scope of variables as constrained as possible. The cool thing is you can repeat the above as necessary to create mini-scopes for common code, nesting them like matryoshka.
Earlier answer before the question revision:
If the question is "what's better," the answer is: Neither. They each have their place, they're useful for different things.
If you're looking for a third solution, you can use partial application (sometimes called currying, though purists have an issue with that). JavaScript doesn't have a built-in partial application feature that doesn't mess with this, but you can easily add one:
(function() {
// Note use of micro-scope here. It's a micro-optimiziation to avoid
// looping up `slice` every time we need it. Mostly it's a justification
// for demonstrating a micro-scope. :-)
var slice = Array.prototype.slice;
Object.defineProperty(Function.prototype, "curry", { // purists: sorry ;-)
value: function() {
var f = this;
var args = slice.call(arguments, 0);
return function() {
return f.apply(this, args.concat(slice.call(arguments)));
};
}
});
})();
Then
function outer(){
var parameter = 3;
this.value = parameter;
$("#something").on("click", inner.curry(parameter));
}
function inner(parameter, target){
target.value = parameter / 2;
}
You've mentioned that there may be a lot of these; if so, you might consider an object with properties instead, so you just curry the object reference rather than a lot of discrete variables.
Example:
(function() {
// Note use of micro-scope here. It's a micro-optimiziation to avoid
// looping up `slice` every time we need it. Mostly it's a justification
// for demonstrating a micro-scope. :-)
var slice = Array.prototype.slice;
Object.defineProperty(Function.prototype, "curry", { // purists: sorry ;-)
value: function() {
var f = this;
var args = slice.call(arguments, 0);
return function() {
return f.apply(this, args.concat(slice.call(arguments)));
};
}
});
})();
function outer() {
var parameter = 3;
setTimeout(inner.curry(parameter));
}
function inner(parameter) {
console.log("Got parameter = " + parameter);
}
outer();

The right way of using a variable - inside or outside a function loop

I was making a loop when suddenly got hit by a question.
Which is supposed to be "the right way":
// code..
$('tr','#my_table').each(function(){
$(this).click(function(){
var show_id = $(this).attr('data-show-id');
// code..
// code..
});
});
// code..
OR
// code..
var show_id = 0; /* HERE */
$('tr','#my_table').each(function(){
$(this).click(function(){
show_id = $(this).attr('data-show-id');
// code..
// code..
});
});
In the first example I create for each tr a new variable show_id.
In the second I use the same global show_id for all of the tr's in the table and I repopulate it on each tr.
So the question wold be: REGARDLESS of the programing language - Is it better practice to create on each loop a new variable which be released when the function exits or "catch" the memory for the entire run and avoid recreating a variable each time?
The variable is not created during the loop. It is needed in the event handler only, which will be executed on its own. Moving the variable (when it's only needed inside) outside has three problems:
access to a higher-scoped variable is a littlebit slower
garbage collection does not collect the value (not memory-efficient)
possible trouble when async behavior in the event handler accesses the variable but the handler is invoked multiple times
The second point is also the answer to your question:
Is it better practice to create on each loop a new variable which be released when the function exits or "catch" the memory for the entire run and avoid recreating a variable each time?
It hardly makes sense to waste the memory for the entire time, creating the function scope is fast. Moving the declaration away from the use of the variable can be considered bad practise, moving it to a different scope even can introduce errors.
Preallocating the memory would make sense if you run on a machine with big memory, and creating/deleting the object (that stays constant for all handlers) is slow.
It all depends, really, on where you need that variable to exist. JS will hoist the variable to the top of the current scope (the one in which is was declared) or create an (evil) global if the var wasn't declared.
It doesn't really matter if you declare a var inside a loop:
for (var i=0;i<10;i++)
{
var j = 1*2;
}
is translated into:
var i, j;
for (i=0;i<10;i++)
{
j = 1*2;
}
A couple of "rules of thumb", though:
if you're using a global variable, you're probably making a mistake
if you're declaring a variable inside a loop, you probably don't need that variable anyway
if you're not declaring variables, try doing this with your script:
(function()
{
'use strict';
//your code here
}());
And debug it until you're implied-global-free.
In your example, you're "offering" the choice between show_id being declared in the global scope (well, $(document).ready(callback scope anyways), or inside the click handler. There's nothing to prevent you from declaring the variable in the each callback either, which wouldn't make much difference in this case, but that's a different matter.
In JS, functions all have their own scope, and you declare a variable in the scope you need it.
Having said that, and just noticing your performance tag, your code is about as bad as it gets in terms of efficiency. Instead of looping over the rows, and binding event handlers all over: delegate the event:
$('#my_table').on('click','tr',function(e)
{
var show_id = e.target.attr('data-show-id');
});
In this code, show_id will be GC'ed after the click handler has returned, if you want the show_id to be preserved, for example, to check when the next row is clicked:
$('#my_table').on('click','tr',(function (show_id)
{
return function(e)
{
console.log('show_id was: ' + show_id);
show_id = e.target.attr('data-show-id');
console.log('and is now: ' + show_id);
};
}()));
console.log(show_id);//undefined
The variable is kept in scope (the function wrapped around the return function is the scope in which show_id as declared, but its return value references that variable, so it's not GC'ed. Outside that returned function, we're in a higher scope, so we can't access the variable at all. What we can do is expose its value:
var someVar = {};
$('#my_table').on('click','tr',(function (show_id)
{
return function(e)
{
show_id = e.target.attr('data-show-id');
someVar.myTableClicks = show_id;
console.log(someVar.myTableClicks);//value of show_id
};
}()));
console.log(someVar.myTableClicks);//undefined
//after a couple of clicks
console.log(someVar.myTableClicks);//some value
Now, we can access the value of show_id anywhere we can access someVar.
Personally, I prefer to keep group code that require some variable to be available:
var access = (function(timer)
{
var speed = 100,
begin = function(callback, interval)
{
speed = +(interval) || speed;
timer = setInterval(callback, speed);
},
stop = function()
{
clearInterval(timer);
};
return {start: start, stop: stop};
}());
In this example, both the start and stop functions require access to the timer var, but I don't want any code from outside to mess with timer's value, so I'm only exposing those functions. AFAIK, the callback argument function can contain timer or speed references, but they won't reference the speed and timer vars I'm trying to shield, because the callback function will, by definition be declared in another scope, and therefore it can't have access to this scope. Even so, if you want to be absolutely sure, you can always do this:
var access = (function(timer)
{
var speed = 100,
begin = function(callback, interval)
{
speed = +(interval) || speed;
timer = (function(timer, speed)
{//masks timer & speed from the higher scope
return setInterval(callback, speed);
}('abc', 'def'));//assign dummy values
timer = setInterval(callback, speed);
},
stop = function()
{
clearInterval(timer);
};
return {start: start, stop: stop};
}());
Personaly I would use:
$("tr","#my_table").each(function(){
$(this).on("click", function(){
var $this = $(this);
var show_id = $this.data("show-id");
// code..
// code..
});
});
Use on("click", function() {...}); instead of .click()
var $this = $(this) is recommended in case you will use it further down in your code else you can ignore it
show_id in this case will not be accessible outside of this scope.
To acces data-* atributes you should use data("-") instead of attr("-")
Memory for all of the variables will be allocated at the entrance of a method, so that the two examples are equivalent. The second example is better because it will be more secure because of the limited scope for variables (will not accidentally use a variable outside the loop).
Depends on your requirements.
First example:
$('tr','#my_table').each(function(){
$(this).click(function(){
var show_id = $(this).attr('data-show-id');
// code..
});
});
Variable is local and can be used inside anonymous function binded with .each or click.
Second Example:
var show_id = 0; /* HERE */
$('tr','#my_table').each(function(){
$(this).click(function(){
show_id = $(this).attr('data-show-id');
// code..
// code..
});
});
Here the variable is Global and thus its scope is valid in the entire script!!!

How can I encapsulate object property so that previous object isn't taken over? (Prototypes/closure.)

I'm starting to get my head around prototyping and closures, within Javascript, but not quite. This example below, my two objects, the second object seems to lose scope/context and takes over the first objects identity.
function broker()
{
var _q = [];
this.add = function(delegate) {_q[_q.length] = delegate; }
this.broadcast = function(message)
{
for(qi = 0; qi < _q.length; qi++)
{
_q[qi](message);
}
}
}
function subscriber(abroker, yourname)
{
me = this;
this.myprop = yourname;
this.subby = function(message){ alert(message + " " + me.myprop + me.dosomething() + secret()); };
this.dosomething = function() {return "...abc";};
function secret(){return "...def";}
abroker.add(this.subby);
}
var thebroker = new broker();
var mysub = new subscriber(thebroker, 'mysub');
var myothersub = new subscriber(thebroker, 'myothersub');
thebroker.broadcast("hello from");
The idea is that there is a common broker object that can invoke a delegate on subscriber objects and execute functions within. But I'm losing scope within the invoked function called by the broker.
output: 2 alerts windows, both output: "myothersub", mysub seems to lose scope?
I have successfully achieved the correct response by explicitly declaring the subby delegate outside of the original object, and referencing the entire object, e.g:
Instead of declaring this.subby within the subscriber object:
mysub.subby = function(message)
{
alert(message + " " + mysub.myprop); // obv the dosomething his hidden
}
thebroker.add(mysub.subby);
Excuse me if any of the above syntax is wrong, from typing directly from memory. It does work in practice, but loses the encapsulation I'm used to.
How can I encapsulate using the original technique within out losing scope/context of the object?
SHORT ANSWER: It looks as though the problem is simply to do with your declaration of me in the subscriber constructor. At the minimum you need to put a var in front of it to make it a local/private variable for each object. So var me = this; instead of me = this;.
EXPLANATION: In JavaScript, when you don't explicitly declare a variable with var, it makes the variable global. So what was happening in your original script is that you created mysub which declared me as a global reference to the this inside the mysub object. But as soon as you created myothersub the global me was overwritten to the this inside the new myothersub object.
Because your subby method created an alert that was based on me it didn't matter which object you called it from since the method in both objects was not using anything local or specific to the object but merely referencing the same global variable -- the this inside the last such object to be created
By simply writing var me = this; instead of me = this; you create a local version of me within a closure each time for each new object you create and not one that is overwritten.
...
PS. Extra tip. You should do this with all variables to ensure that you have as few globals as possible, especially when you don't mean them to be global! Therefore I'd make the same declaration for the variable qi inside the broker constructor. You could do this simply by declaring inside the loop conditions, e.g., for (var qi = 0; qi < _q.length; qi++). That would be enough to stop qi being a global variable.
However, in the interests of keeping your code easy to read it's best to declare all variables at the top of a function. So I would recommend simply rewriting the broadcast method thus:
this.broadcast = function(message) {
var qi, // STOPS `qi` BECOMING A GLOBAL
ql = q.length; // SO DON'T HAVE TO CHECK LENGTH OF `q` EVERY LOOP
for(qi = 0; qi < ql; qi += 1) {
_q[qi](message);
}
};
If you haven't come across him before, Douglas Crockford is a really good go-to writer on JavaScript when it comes to closures, object creation and just good code writing conventions. There's a bunch of tips on this page and you can find videos of him lecturing on the topic quite easily. All this really helped me when I started looking into closures and other aspects of JavaScript more closely; hope it helps you too.

Understanding closure in Javascript

I'm trying to wrap my head around closures in Javascript.
Here is an example from a tutorial:
function greeter(name, age) {
var message = name + ", who is " + age + " years old, says hi!";
return function greet() {
console.log(message);
};
}
// Generate the closure
var bobGreeter = greeter("Bob", 47);
// Use the closure
bobGreeter();
The author said that this is an effective way of using closure to make private variables, but I don't get the point.
Could someone enlighten the benefits of coding like this?
A closure is a pair of a function and the environment in which it was defined (assuming lexical scoping, which JavaScript uses). Thus, a closure's function can access variables in its environment; if no other function has access to that environment, then all of the variables in it are effectively private and only accessible through the closure's function.
The example you provided demonstrates this reasonably well. I've added inline comments to explain the environments.
// Outside, we begin in the global environment.
function greeter(name, age) {
// When greeter is *invoked* and we're running the code here, a new
// environment is created. Within this environment, the function's arguments
// are bound to the variables `name' and `age'.
// Within this environment, another new variable called `message' is created.
var message = name + ", who is " + age + " years old, says hi!";
// Within the same environment (the one we're currently executing in), a
// function is defined, which creates a new closure that references this
// environment. Thus, this function can access the variables `message', `name',
// and `age' within this environment, as well as all variables within any
// parent environments (which is just the global environment in this example).
return function greet() { console.log(message); };
}
When var bobGreeter = greeter("Bob", 47); is run, a new closure is created; that is, you've now got a new function instance along with the environment in which it was created. Therefore, your new function has a reference to the `message' variable within said environment, although no one else does.
Extra reading: SICP Ch 3.2. Although it focuses on Scheme, the ideas are the same. If you understand this chapter well, you'll have a good foundation of how environments and lexical scoping work.
Mozilla also has a page dedicated to explaining closures.
The purpose of a closure is so that the variables you use inside a given function are guaranteed to be "closed" which means they do not depend on external variables - they only depend on and use their arguments. This makes your Javascript methods closer to a pure function, that is, one that returns the same value for the same given arguments.
Without using closures, your functions will be like Swiss cheese, they will have holes in them. A closure plugs up those holes so the method doesn't depend on variables higher in the scope chain.
Now, up until this point, my answer has been simply about organizing your code and style. So take this simple example. At the line with the comment, I invoke a function and the value of the variable a is captured for future use.
var a = "before";
var f = function(value) {
return function()
{
alert(value);
}
} (a); //here I am creating a closure, which makes my inner function no longer depend on this global variable
a = "after";
f(); //prints "before"
Now, why would you need to do this? Well, here's a practical example. Consider the following code that uses jQuery to add 5 links to the document. When you click a link, you would expect it to alert the number associated with the link, so clicking the first you would think would alert 0, and so on. But, this is not the case, each link will alert the value of 5. This is because the function I define depends on the variable i which is being modified outside the context of the function. The function I pass into bind is a Swiss cheese function.
for (var i = 0; i < 5; i++)
{
var a = $('<a>test link</a>').bind('click', function(){
alert(i);
});
$(a).appendTo('body');
}
Now, let's fix this by creating a closure so each link will alert its correct number.
for (var i = 0; i < 5; i++)
{
var fn = function (value) {
return function() {
alert(value);
};
} (i); //boom, closure
var a = $('<a>test link</a>').bind('click', fn);
$(a).appendTo('body');
}
I don't think this is a good example for private variables, because there are no real variables. The closure part is that the function greet can see message (which is not visible to the outside, hence private), but it (or anyone else) is not changing it, so it is more of a constant.
How about the following example instead?
function make_counter(){
var i =0;
return function(){
return ++i;
}
}
var a = make_counter();
console.log(a()); // 1
console.log(a()); // 2
var b = make_counter();
console.log(b()); // 1
console.log(a()); // 3
A better example may be
function add(start, increment) {
return function() {
return start += increment;
}
}
var add1 = add(10, 1);
alert(add1()); // 11
alert(add1()); // 12
Here, every time you call the returned function, you add 1. The internals are encapsulated.
The returned function still has access to its parents variables (in this case, start and increment).
On a lower level of thinking, I think it means that the function's stack is not destroyed when it returns.
Once you "get it" you will wonder why it took you so long to understand it. That's the way way I felt anyways.
I think function scope in Javascript can be expressed fairly concisely.
The function body will have access to any variables that were visible in the lexical environment of the function declaration, and also any variables created via the function's invocation -- that is, any variables declared locally, passed through as arguments or otherwise provided by the language (such as this or arguments).
It's called "closures" because they are "closed" around free variables, and there are much more ways to use it then only hiding state. For example, in functional programming, where closures came from, they are often used to reduce parameters number or set some constant for a function. Let's say you need function goodEnough() that will test if some result is better then some threshold. You can use function of 2 variables - result and threshold. But you can also "enclose" your constant inside function:
function makeThresholdFunction(threshold) {
return function(param) {
return (param > threshold);
}
}
var goodEnough = makeThresholdFunction(0.5);
...
if (goodEnough(calculatedPrecision)) {
...
}
With closures you can also use all the tricks with functions such as their composition:
function compose(f1, f2) {
return function(arg) {
return f1(f2(arg));
}
}
var squareIncremented = compose(square, inc);
squareIncremented(5); // 36
More on closure design and usage can be found at SICP.
I found this a pretty helpful article.
When is a function not a function?
//Lets start with a basic Javascript snippet
function generateCash() {
var denomination = [];
for (var i = 10; i < 40; i += 10) {
denomination.push(i);
}
return denomination;
}
This a basic function statement in Javascript that returns an array of [10,20,30]
//--Lets go a step further
function generateCash() {
var denomination = [];
for (var i = 10; i < 40; i += 10) {
denomination.push(console.log(i));
}
return denomination;
}
This will print 10, 20 ,30 sequentialy as the loop iterates, but will return an array of [undefined, undefined, undefined], the major reason being we are not pushing the actual value of i, we are just printing it out, hence on every iteration the javascript engine will set it to undefined.
//--Lets dive into closures
function generateCash() {
var denomination = [];
for (var i = 10; i < 40; i += 10) {
denomination.push(function() {
console.log(i)
});
}
return denomination;
}
var dn = generateCash();
console.log(dn[0]());
console.log(dn[1]());
console.log(dn[2]());
This is a little tricky, what do you expect the output will be, will it be [10,20,30]? The answers is no, Lets see how this happens. First a Global execution context is created when we create dn, also we have the generatecash() function. Now we see that as the for loop iterates, it creates three anonymous function objects, it might be tempting to think that the console.log within the push function is getting fired too, but in reality it is not. We haved invoked generateCash(), so the push function is just creating three anonymous function objects, it does not trigger the function. At the end of the iteration, the current local context is popped from the execution stack and it leaves the state of i : 40 and arr:[functionobj0(), functionob1(), functionobj2()].
So when we start executing the last three statements, all of them output 40, since it is not able to get the value of i from the current scope, it goes up the scope chain and finds that the value of i has been set to 40. The reason all of them will fire 40 is beacause every single component of dn lies in the same execution context and all of them on being not able to find the value of i in their current scope will go up the scope chain and find i set as 40 and output it respectively

I know what a closure is, but I still dont understand why (or when) you would use them

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.
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;
}());
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.
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:
Javascript Closures
* 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).
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
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.
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
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.

Categories