16

I've seen others using the following pattern.

var bar = function foo(){};
console.log(bar); // foo()
console.log(foo); // ReferenceError: foo is not defined

But why? I can see the point if both were declared, but they're not. Why is the reason?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
98374598347934875
  • 535
  • 1
  • 4
  • 12
  • 3
    What you've got there is an anonymous function that has a name. The only reason I know to do that is when you're debugging into the foo() function the stack trace will show the name rather than just 'anonymous function'. – Ben Clayton Mar 12 '12 at 12:47
  • 1
    Related: [Why use named function expressions?](/q/15336347/4642212), and more generally: [var functionName = function() {} vs function functionName() {}](/q/336859/4642212). – Sebastian Simon Sep 30 '21 at 15:34
  • @BenClayton _“anonymous function that has a name”_ is an oxymoron. It’s a named function expression. – Sebastian Simon Sep 30 '21 at 15:40

5 Answers5

8

As mentioned by others, using the first form in your example (a named function expression) can help with debugging, although with the recent improvements in built-in developer tools in browsers, this argument is becoming less persuasive. The other reason for using a named function expression is that you can use the function name as a variable within the body of the function rather than the now-deprecated in ES5 arguments.callee.

However, named function expressions are incorrectly and problematically implemented in Internet Explorer < 9 and should generally be avoided when you're targeting those browsers. See Juriy Zaytsev's excellent article on the subject for more information.

Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • +1 for mentioning the visibility of function name in the inner scope. – Fabrizio Calderan Mar 12 '12 at 12:59
  • +1, as seen in Mozilla's official documentation `"The function name can be used only within the function's body."` https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions#Differences – Adriano Nov 10 '14 at 09:41
7

When debugging an application, it is easier to know what is calling what in the call stack when "named" anonymous functions are used. So it is a way to give a name to an anonymous function for debugging purposes.

Try this and look at the callstack in a debugger:

myDiv = document.getElementById("myDiv");

myDiv.onclick = function OnClick(){
    debugger;
    //do something
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
mpm
  • 20,148
  • 7
  • 50
  • 55
  • 4
    Beware of using named function expressions in IE < 9: the implementation in those browsers is broken. http://kangax.github.com/nfe/ – Tim Down Mar 12 '12 at 13:01
  • To elaborate, the assignment of a function to the onclick attribute is broken in earlier versions of ie, not the syntax function OnClick() {}. – Zoidberg Mar 12 '12 at 14:36
  • 1
    @Zoidberg: No, that's not what I meant. The syntax `var foo = function bar() {};` is itself definitely broken in IE < 9. Also, DOM0 event handler properties (e.g. `myDiv.onclick = function() {};`) work fine in IE. I imagine you're thinking of `setAttribute()` (e.g. `myDiv.setAttribute("onclick", "alert('click')");`), which **is** broken in old IE. – Tim Down Mar 12 '12 at 15:20
  • I have used function () {} in IE 8 and less and it works just fine for me. Does it not compile, please give some detail on what broken is. – Zoidberg Mar 12 '12 at 16:04
  • 2
    @Zoidberg: The detail is all in the article I linked to (http://kangax.github.com/nfe/). While it will usually work, the problems with it are subtle, meaning it can lead to hard-to-find bugs. – Tim Down Mar 12 '12 at 16:19
  • @TimDown I just noticed the difference in syntax. var foo = function bar() {}, I thought you meant var foo = function () {} (no bar). I have never used the syntax var foo = function bar() {} before and I have never had the need to. Thanks for the heads up on this. If he was to change it to myDiv.onclick = function () {..} it wouldn't break in IE 8 and less. – Zoidberg Mar 12 '12 at 16:32
2

They are naming an anonymous function because it makes debugging easier. When debugging, you will see a call to "foo" in the call stack rather than a bunch of calls to "anonymous".

jbabey
  • 45,965
  • 12
  • 71
  • 94
2

The only reason I can imagine for this is to give the function a desired name. This helps debugging as the inspector uses the function object's name attribute. Try this:

var bar = function foo(){};
console.log(bar.name); // foo

If you put some real code inside foo and add a breakpoint to the JavaScript debugger in your browser, you will see the function as foo in the call stack.

Esteban
  • 2,540
  • 21
  • 27
0

The function definition (or literal) has 4 parts. 1. The reserved word function 2. An optional name which can be used by debuggers or by the function to call itself recursively. 3. The parameters and 4. The body of the function wrapped by { }

Outside of the function scope foo doesn't exist. But since you assigned the function to the variable bar you can call it using the method invocation bar and since bar is defined you can print it.

If you're interested in JavaScript you should really consider getting Douglas Crockford's book Javascript: The Good Parts

Leonard Garvey
  • 1,517
  • 12
  • 8