These aren't very good examples. You shouldn't break up small pieces of code just to avoid nested callbacks.
"Well, until you have two or three callbacks that respond differently to fs.readFile and you start running out of function names, right?"
That's a red flag right there. If you can't figure out a unique name for the callback, perhaps it's not worth naming it.
If you have a reusable piece of code, or it's just getting unwieldy (~3 levels deep or so), then you should consider breaking it out into it's own function. But otherwise for simple things I think it's more readable to have it inline.
It's unfortunate JavaScript's anonymous function syntax is so verbose. It would be much more pleasant with lightweight syntax (CoffeeScript, perhaps?)
It is verbose, but on the other hand, I like the fact that the syntax for anonymous functions is pretty much almost the same as named functions.
Like what pg said somewhere (forgot where), having anonymous functions is a red flag in the language, because there shouldn't be any distinction between anonymous functions and named functions. Javascript kind of gets this right.
I believe CoffeeScript gets this even more right, by having a single way to declare functions which is also concise?
I think you make good points. The reason I used these simple examples was only for simplicity and to illustrate that named function callbacks can be used within closures rather than littering your global space with function declarations. More complex examples would probably have taken away from the core point of the article.
Absolutely - the code can be re-factored - but your example doesn't demonstrate that you can used named functions/callbacks within closures to further organize code.
You mean the nested versions? Just because it's not the most efficient way possible to do something does not automatically mean it's a 'performance issue'. If you're doing it once, or if it's some user based event like a button click, the difference will not be noticeable. If this is happening in a loop, perhaps then you might be in need of re-factoring. But in this example it would probably hardly help since it's reading and writing files, and chances are that's going to slow you down more.
EDIT: took out function hoisting stuff, it doesn't get hoisted after a quick check.
It's certainly no worse than the first example with the anonymous functions inline. But yes, worse than the second example, since it's creating closures on each invocation.
The closures aren't meant to be more performant, they simply allow you to separate your code. It's not fair to compare the unnamed function example with the closure example, since the first doesn't create closures. If it did - which would be necessary to create both functions - the examples would be equally performant.
The first and third examples are both creating closures. It doesn't matter if they're named or not. Any time you see the "function" keyword within another function, that's a closure.
Check out the performance of these three styles. #1 and #3 are almost identical, #2 is significantly faster: http://jsperf.com/closures-perf
You make a good point and thanks for the performance link. I should have been more clear. The first and third examples are only comprable in the way they create closures - which is equivalent, but they are meant to demonstrate different things. The first demonstrates nested callbacks while the last example demonstrates named functions that are organized by closures.
But this is happening anyways with unnamed functions - they will be defined any time the top level function is called. The difference is really just whether or not you are naming your functions.
My reading of the title followed the first commenter.
For years we've been begging for locally bound function declarations so we don't have to explicitly pass variables to callbacks and so we don't pollute the global namespace with worker function names.
This article then proceeds to throw all that away so we can have named functions. Worse, you can have names and locality that he ignores:
function bigGuy() {
function littleWorker() { /* stuff */ }
begin(littleWorker);
}
So my question, why do this? What are the benefits?
Is this not an obvious effect of first class functions? Was it necessary to rename "functions" to "named callbacks"? Can't you do basically exactly this with function pointers in C?
Hopefully v8 will implement some of the things from Mozilla's Javascript 1.8 like generators, which will make evented programming more interesting.
"Well, until you have two or three callbacks that respond differently to fs.readFile and you start running out of function names, right?"
That's a red flag right there. If you can't figure out a unique name for the callback, perhaps it's not worth naming it.
If you have a reusable piece of code, or it's just getting unwieldy (~3 levels deep or so), then you should consider breaking it out into it's own function. But otherwise for simple things I think it's more readable to have it inline.
It's unfortunate JavaScript's anonymous function syntax is so verbose. It would be much more pleasant with lightweight syntax (CoffeeScript, perhaps?)