1

Possible Duplicate:
What is the difference between a function expression vs declaration in Javascript?

Is there a MAJOR difference between declaring functions in these ways:

  1. function foo(){
         alert('BAR');
    }
    
  2. var foo = function (){
         alert('BAR');
    }
    
  3. var foo = function bar(){
         alert('BAR');
    }
    

I was told here that:

It happens at a different time, and results in a variable referring to an anonymous function. A function declaration happens prior to any stepwise code executing in the scope, and results in both a binding and a function with a proper name.

Can the way I declare my function really affect the efficiency of my code, and if so which way is best to use?

Community
  • 1
  • 1
Naftali
  • 144,921
  • 39
  • 244
  • 303
  • 3
    Did you do any research on this matter before asking it? The web is full of explanations about this. – Angel Jun 14 '12 at 15:14
  • @Angel yes I did, and I got very very mixed opinions.... – Naftali Jun 14 '12 at 15:16
  • @Somebodyisintrouble you can call any of them on event. – Naftali Jun 14 '12 at 15:18
  • @Somebodyisintrouble: You can call any of them via an event. – T.J. Crowder Jun 14 '12 at 15:21
  • 2
    The downvotes on the question seem **very** harsh to me. (The close votes make sense.) – T.J. Crowder Jun 14 '12 at 15:22
  • @T.J.Crowder how can i call second one –  Jun 14 '12 at 15:22
  • @T.J.Crowder yea, I don't know why the downvotes. I had searched for this on SO before posting, and someone else found it. – Naftali Jun 14 '12 at 15:23
  • In a nutshell, named function expressions are useful for one thing only — descriptive function names in debuggers and profilers. Well, there is also a possibility of using function names for recursion, but you will soon see that this is often impractical nowadays. If you don’t care about debugging experience, you have nothing to worry about. http://kangax.github.com/nfe/. – Justin Blank Jun 14 '12 at 15:18
  • @T.J.Crowder: Why do you distinguish between the two. If it should be closed, then that's saying it should never have been asked based the reason given. Seems DV worthy for that reason. *(Speaking in general, not necessarily about this. I've given no votes on this post.)* –  Jun 14 '12 at 15:29
  • @amnotiam that is not what a downvote is for. – Naftali Jun 14 '12 at 15:30
  • @Neal: Sure it is. It rates the quality of the post, and the research effort of OP. If it doesn't belong here, or if it has already been asked *(showing lack of research)*, then those are reasons to DV. *(Again, not talking about your Q necessarily.)* –  Jun 14 '12 at 15:32
  • FWIW, It seems to me that you're asking about if/how each way affects the efficiency of your code. I don't see how the proposed duplicate is asking that. But then again, I don't see how your accepted answer answers it either. –  Jun 14 '12 at 15:37

1 Answers1

7

Yes, there is a major difference.

The first is a function declaration. It happens upon entry to an execution context, prior to any step-by-step code being processed. It cannot be within any kind of control block (e.g., it's not legal in the body of an if statement; however, most browsers will try to accommodate it if you do that — sometimes resulting in very surprising behavior — at variance with the spec). It results in a named function.

The second is a function expression (specifically, an anonymous function expression). Like all expressions, it's processed when it's encountered in the step-by-step execution of the code. And like all expressions, it can be within a control block. It results in a function with no name assigned to a variable that has a name.

The third is a named function expression. It's a function expression like the above, but the function is also given a name. You want to avoid these with IE8 and earlier, since IE will actually get it quite wrong, creating two separate functions (at two different times). (Basically, IE treats it as both a function declaration and a function expression.) IE9 finally gets this right.

Note that your second and third examples rely on automatic semicolon insertion; because those are both assignment statements, they should end with a ; (after the ending } of the function).

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    Browsers do allow function declarations within blocks in non-strict mode, but only because they have non-standard extensions to handle it. – Tim Down Jun 14 '12 at 15:19
  • @TimDown: Not all do. Firefox's SpiderMonkey engine doesn't, for instance. Not even in relatively straightforward situations where if they were stepwise code, they'd always run (like a try block with no preceding branching). – T.J. Crowder Jun 14 '12 at 15:20
  • Firefox does handle it, in that it doesn't throw an error. – Tim Down Jun 14 '12 at 15:23
  • @TimDown But does spidermonkey? I don't have firefox 3.x or whatever to test – Esailija Jun 14 '12 at 15:24
  • @Tim: Just tried it with Firefox 13, and it allowed it: http://jsbin.com/atusib And I happened to have Firefox 3.6.15 lying around in a Windows VM, and *it* allowed it too! Very, very surprised by that, as I distinctly recall work I did about a year ago failing only in FF because I'd blindly wrapped the contents of a function in a `try..catch` and hadn't noticed it had a declaration within it. And it wasn't strict code, either (the project in question didn't use it). I wonder what was different... – T.J. Crowder Jun 14 '12 at 15:26
  • @Esailija: I'm pretty sure it does. See https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope#Conditionally_defining_a_function, which has been on MDN since 2008. – Tim Down Jun 14 '12 at 15:32
  • @TimDown: Don't know if you saw the above, but at least Firefox 3.6.15 supports what you're saying. Thanks for that. Now I want to go back in time and see what was going on with the code I mentioned above. :-) I know it wasn't strict, but I've played with that jsbin a bit and cannot get FF 3.6.15 to replicate what I remember. And I **know** it was Firefox. Enh, whatever. :-) But note: http://jsbin.com/atusib/5 The behavior can be very, very surprising (FF treats them like expressions, Chrome and IE like declarations). – T.J. Crowder Jun 14 '12 at 15:38