6

Can someone please explain the difference between the following function definitions?

var alertMessage = function alertMessage(message) {
  alert(message);
}

var alertMessage = function(message) {
  alert(message);
}

What are the implications of each? Thanks!

  • Relevant analysis: http://yura.thinkweb2.com/named-function-expressions/ (in particular see the section "Named function expressions") – Roatin Marth Mar 30 '10 at 17:37
  • Read this answer I think you will find any information you need: http://stackoverflow.com/questions/336859/javascript-var-functionname-function-vs-function-functionname/338053#338053 – Felix Kling Mar 30 '10 at 17:41

2 Answers2

2

Both are function expressions, basically the difference is that the first is named, and the second one is anonymous.

For example:

var test = function test(message) {
  alert(message);
};

var test1 = function(message) {
  alert(message);
};

test.name; // "test"
test1.name // "" or "anonymous"

Note: The name property of function objects exist on some implementations, but it's non-standard.

Also, the name of function expressions it's useful for debugging, as you can inspect the call stack to see where you are.

This identifier is only accessible from inside the FunctionBody itself:

(function foo(){
  typeof foo; // "function"
})();
typeof foo; // "undefined"

However there is a bug on the JScript implementation (in all versions of IE), which this name is leaked to its enclosing scope.

Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
  • 1
    The bug's worse than that, it also ensures that the function gets created twice, once at the start of the enclosing scope and once at assignment time. If you assigned to a variable with a different name, you'd have two non-equal copies of the same function (which can cause you problems if you're making a class to compare against with `instanceof`!). Best: avoid named inline function expressions. – bobince Mar 30 '10 at 18:47
  • Yes @bobince the behavior is bad enough that it's become a simple "do not do that" rule for me, which is a shame since that's so useful. Erlang has no way of doing this (basically a "letrec") and it's a real pain. – Pointy Mar 30 '10 at 18:53
  • @bobnice, @Pointy: Yes, I think that is one of the most horrendous deviation of ECMA Standard, and do you know guys, that this bug is still present on the **IE9** Platform Preview?!!, the identifier leaks to its enclosing scope, but seems that only one function instance is created... :-( – Christian C. Salvadó Mar 30 '10 at 20:51
  • Thanks everyone, this has been a great help! – Matthew Willhite Mar 30 '10 at 21:53
2

Both definitions are function expressions, as opposed to function declarations, or functions created by the Function constructor. They both assign a function to the variable alertMessage. The difference is that the first function is named, while the second is anonymous.

Named functions are usually used in function declarations, eg

function alertMessage(message) { ... }

In that case, the function declaration creates a variable in the current scope called alertMessage that references that function. Function declarations are hoisted to the top of the current scope, so you can call declared functions before they're defined in you js file.

A named function used in a function expression (such as the original question) does not create this variable, or get hoisted to the top of the execution scope, so by convention most function expressions are anonymous. The only benefits to naming a function expression are that the name variable is bound within the function (although as CMS mentions, this is implementation dependent) and the function name is output from the function's toString method. This can be useful during debugging (rather than having Firebug output (?) for a huge list of anonymous function calls).

Much more detail at MDC

alunny
  • 908
  • 4
  • 10