Reactgular
Reactgular

Reputation: 54801

Return named function from constructor function

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

Answers (2)

axelduch
axelduch

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

Scott Sauyet
Scott Sauyet

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:

  • IE, at least through IE8, created two copies of such functions for every one you meant to create.

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

Related Questions