Reputation: 54801
I've never seen this syntax done before, but it's used all throughout the Angular source code.
function something() {
// do stuff...
return function foo() {
// do stuff..
};
}
// later
var x = something();
From what I can tell foo()
is being used as a closure function, but why does the function have a name? I thought giving a closure function a name was invalid syntax, but this appears to run fine in the browser.
Is there anything different between the above and below code? if so, what?
function something() {
// do stuff...
return function() {
// do stuff..
};
}
// later
var x = something();
Upvotes: 4
Views: 815
Reputation: 10849
An named function expression is a cool thing that allows you to ease caching and calls from withing that same function (a recursive call).
For instance what if you wanted to know how many times a function has been called:
var anonNamedFn = function fn() {
fn.cache = fn.cache || {
callCount: 0
};
fn.cache.callCount += 1;
};
Another example with recursion:
var anonNamedFn = function fn(n) {
if (n > 0) {
return fn(n-1);
}
};
It allows a disambiguation of this
context.
UPDATE
It helps at debugging, since it shows the name of your function if you choose a wise one
Be careful though, because only true browsers support well this feature (IE9+ for IE).
EDIT Anonymous named function => named function expression Paul S.
Upvotes: 3
Reputation: 50807
This has nothing to do with the function being included in a closure.
There is a real difference between a function declaration:
function myFunc() { /* ... */ }
and a function expression:
var myFunc = function() { /* ... */ };
or
var myObj = {
myFunc: function() { /* ... */ },
// ...
}
In these cases, the function expressions were anonymous. What you're discussing is a named function expression:
var myFunc = function privateName() { /* ... */ };
(Note that the internal privateName
does not have to match myFunc
.)
These have two distinct advantages over anonymous ones, and one disadvantage. The disadvantage is that:
The advantages are:
The names show up in debuggers, making it easier to find your way around.
The names are available inside the function, and nowhere else, so you can use them for
recursion or other internal usage without polluting the global namespace and without
depending on deprecated features like argument.callee
.
Kangax wrote perhaps the definitive article on them: Named function expressions demystified.
Upvotes: 5