tags:

views:

971

answers:

4

What is the difference between the following lines of code:

function foo() { return 5; }


var foo = function() { return 5; }


var foo = function foo() { return 5; }

What is a named function expression and how do browsers deal with these constructs differently?

What do the responses to a similar question (http://stackoverflow.com/questions/336859/javascript-var-functionname-function-vs-function-functionname) not get exactly right?

+3  A: 

There are some interesting nuances to the function construct in javascript and how function declarations are treated differently from function expressions.

Until now, most of the useful information was littered across two newsgroups: comp.lang.javascript and https://mail.mozilla.org/listinfo/es-discuss.

For the first time, a very clear, comprehensive and cohesive treatise of this subject is provided ( http://yura.thinkweb2.com/named-function-expressions/ ) by Juriy "kangax" Zaytsev. Even if you think you know javascript cold inside-out, you'll learn something about all the javascript (ecmascript) implementations out there :)

Enjoy!

All credit goes to Mr. Zaytsev (and the people he thanks at the bottom of his webpage :)

P.S. I thought this topic would be of interest to the stackoverflow javascripters, and according to the FAQ, self-answered questions are welcomed too.

Faisal Vali
Not sure why this was downvoted. That's a great article. +1
Triptych
A short version of the answer would have been nice. There is no guarantee that the link is working in the future.
Nifle
@Nifle - Good point.
Triptych
@Nifle - yes that is true - i'll try and edit my post when i get some more time if no one has summarized it by then
Faisal Vali
I added a couple more sections to an article — one on WebKits `displayName` (http://yura.thinkweb2.com/named-function-expressions/#webkit-displayName) and one on future considerations (http://yura.thinkweb2.com/named-function-expressions/#future-considerations). I also updated few sections here and there, added explanation of why function declarations are not allowed within blocks; what happens when named function expression is used in undeclared assignment in IE, etc. Enjoy.
kangax
A: 

The first statement depends on the context in which it is declared.

If it is declared in the global context it will create an implied global variable called "foo" which will be a variable which points to the function. Thus the function call "foo()" can be made anywhere in your javascript program.

If the function is created in a closure it will create an implied local variable called "foo" which you can then use to invoke the function inside the closure with "foo()"

EDIT:

I should have also said that function statements (The first one) are parsed before function expressions (The other 2). This means that if you declare the function at the bottom of your script you will still be able to use it at the top. Function expressions only get evaluated as they are hit by the executing code.

END EDIT

Statements 2 & 3 are pretty much equivalent to each other. Again if used in the global context they will create global variables and if used within a closure will create local variables. However it is worth noting that statement 3 will ignore the function name, so esentially you could call the function anything. Therefore

var foo = function foo() { return 5; }

Is the same as

var foo = function fooYou() { return 5; }
Alex
`fooYou` is not ignored. It is visible in function body, so the function can reference itself (e.g. to implement recursion).
el.pescado
A: 

Here's a good article on named function expressions. Function expressions vs declarations are addressed in the first section.

Evan Meagher
A: 

They're actually really similar. How you call them is exactly the same, but the difference lies in how the browser loads them into the execution context.

function declarations loads before any code is executed.

While function expressions loads only when the interpreter reaches that line of code.

So if you try to call a function expression before it's loaded, you'll get an error

But if you call a function declaration, it'll always work. Cuase no code can be called until all declarations are loaded.

ex. Function Expression

alert(foo()); // ERROR! foo wasn't loaded yet
var foo = function() { return 5; } 

ex. Function Declaration

alert(foo()); // Alerts 5. Declarations are loaded befoer any code can run.
function foo() { return 5; } 

As for the second part of your questions.

var foo = function foo() { return 5; } is really the same as the other two. It's just that this line of code used to cause an error in safari. I'm not sure if it still does. Haven't tried.

Khon Lieu