8

What's the point of naming function expressions if you can't really reference them by the names you give them?

var f = function g() {
    console.log("test");
};

g(); // ReferenceError: g is not defined
  • 1
    https://kangax.github.io/nfe/ – SLaks Dec 08 '15 at 19:50
  • Isn't that function callable like `f()`? – cat Dec 08 '15 at 19:53
  • I know I'm being a little picky here, but it's NOT an anonymous function if it is named. They are opposites. – trex005 Dec 08 '15 at 19:56
  • Never in my post did I say that a function can be both, anonymous and named, at the same time. –  Dec 08 '15 at 20:00
  • 2
    @trex005 if you wanted to be helpful as well as picky, you could say the example given is called a [function expression](https://developer.mozilla.org/en/docs/web/JavaScript/Reference/Operators/function) :P – Aprillion Dec 08 '15 at 20:03

5 Answers5

11

Oh, but you can reference them by that name. Those names just only exist inside the scope of the function.

var f = function g() {
    // In here, you can use `g` (or `f`) to reference the function
    return typeof g;
};

console.log( typeof g );
// It only exists as `f` here
console.log( f() );

DOCS: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function#Named_function_expression

vsync
  • 118,978
  • 58
  • 307
  • 400
gen_Eric
  • 223,194
  • 41
  • 299
  • 337
  • 3
    Note that one reason for this is that using `f` to refer to the function here is dangerous - e.g. `f` could be redefined to `null` after the function expression, and then trying to call `f()` within the function would throw. – nrabinowitz Dec 08 '15 at 19:57
9

One advantage that I find particularly useful is that it helps when debugging.

When an error occurs, you see the function name in the stacktrace in the console. Otherwise the line in the stacktrace would only refer to an anonymous function.

You can also make the purpose of the function clearer by giving it a name.

lex82
  • 11,173
  • 2
  • 44
  • 69
  • Could you elaborate so this doesn't appear more as a comment? – Sterling Archer Dec 08 '15 at 19:55
  • 1
    Done. However, I don't think there is much more to elaborate on this aspect. Anyway, I think it should be part of the answers. – lex82 Dec 08 '15 at 20:01
  • 1
    In this particular example, when the function is assigned to a variable, the function name will be inferred as `f` if you leave out the `g`. But I understand it would be useful in other contexts. – kamilk Dec 08 '15 at 20:05
  • You are right, I didn't really pay attention to the example. – lex82 Dec 08 '15 at 20:08
4

It's important if you create a recursive function that is passed around. When you name a function it then knows about itself, within its own scope.

Here I've created a sort of factory function that creates recursive functions. For the recursive functions to work properly they need to know about themselves.

You can imagine this applied in a broader sense, like returning a recursive function as a module export.

var 
func = (function () {
  return function rec (a) {
    console.log(a);
    return a >= 5 ? 'done' : rec(a + 1);
  };
}),
invoke = function (f, args) {
  return f.apply(null, args);
};

console.log(
  invoke(func(), [1])
);
Oka
  • 23,367
  • 6
  • 42
  • 53
1

By very definition, what you have defined is not an anonymous function:

function [name]([param[, param[, ... param]]]) {
   statements
}

Name:

The function name. Can be omitted, in which case the function becomes known as an anonymous function.

Furthermore, a lot of peole would consider

var f = function() {
     return 'test';
 };

not to be an anonymous function since you can now invoke it by var name f() and can now pass the function as a parameter to other functions by the name functionThatTakesCallback(f).

In my head, a true anonymous function has no name whatsoever such as something passed to a call back:

$('#id').on('click', function(){
  console.log("I am anonymous");
});

or as a function run immediately:

(function(when){
  console.log("run me :", when);
})("right now");

With the syntax you are using now, in ES6 (most non IE browsers implement this feature), f.name is g. This is useful when debugging

mistahenry
  • 8,554
  • 3
  • 27
  • 38
1

You could use it to recur:

var f = function g (n, m) {
    if (n>0) {
        return g(n - 1, m = m + 'meta');
    }
    return m + 'test';
};

console.log(f(10, 'super'));