1

A. function foo( ){ }

B. var foo = function foo( ){ }

I write all my JavaScript functions in the A fashion because I think B is redundant. My coworker likes to go in and do mass find/replace to rewrite my functions like B because he says it's best practice according to airbnb.

  1. What is the fundamental/practical difference between the two?

  2. Is there danger of him breaking my code by doing this?

  3. Is one better practice than the other (can you cite any sources)?


  • 2
    Have you taken a look at this? http://stackoverflow.com/questions/336859/var-functionname-function-vs-function-functionname – dowomenfart Feb 24 '15 at 13:14
  • [Yours is better](http://blog.niftysnippets.org/2010/03/anonymouses-anonymous.html). Can you link those "airbnb best practises" your coworker claims to follow? – Bergi Feb 24 '15 at 13:16
  • There is no better. It all depends on the situation. – Stephan Bijzitter Feb 24 '15 at 13:18
  • 1
    Isn't airbnb some kind of rental/booking site? When did they become a trusted expert on JavaScript best practices? – Anthony Grist Feb 24 '15 at 13:22
  • @Bergi: Hey, great link. ;-) But note that (B) uses an NFE, not an anonymous function. – T.J. Crowder Feb 24 '15 at 13:24
  • @T.J.Crowder: Oops, thank you. Looking at your answer :-) – Bergi Feb 24 '15 at 13:27
  • 1
    re AirBNB, a lot of people like their comprehensive [styleguide/code conventions.](https://github.com/airbnb/javascript/) – Andy Feb 24 '15 at 13:44
  • 1
    Good link @Andy. And quelle surprise, I don't see anything under "Functions" there that supports the OP's co-worker's belief that they recommend not using function declarations. I do see something you could ***misread*** that way, but it's a misreading. – T.J. Crowder Feb 24 '15 at 14:01
  • This is the airbnb standard that he says we should rigorously follow: https://github.com/airbnb/javascript – Justice Gödel Conder Feb 24 '15 at 14:56
  • @JusticeGödelConder: As I said above and in my answer, there's nothing in there saying not to use function declarations. If he thinks there is, he's mistaken. – T.J. Crowder Feb 24 '15 at 18:00

1 Answers1

4

Preamble: Yours is called a function declaration. His is called a named function expression (NFE). These are discussed in some detail in this question and its answers, but addressing your specific questions:

...he says it's best practice according to airbnb...

If he's talking about these Airbnb style guidelines, I don't see anything there to support that claim. I do see a couple of things you could misread that way, but it would be misreading. It says not to declare functions inside control flow blocks, e.g.:

// bad
if (currentUser) {
  function test() {
    console.log('Nope.');
  }
}

And that's quite true, that's not just bad, it's invalid according to the current specification. You can only declare functions at the top level of a scope (e.g., at global scope outside of all control flow structures like if, while, for, and so on; or at the top level of a function outside of all control flow structures). The example above is invalid because it's within the block connected to the if. (In ES6, for web engines only, it's tolerated in a very specific subset of situations — TL;DR: Don't do it.)

But that's not a blanket "don't use function declations," not remotely.

What is the fundamental/practical difference between the two?

Your form is processed upon entry to the scope in which the function is declared, before any step-by-step code is executed (sometimes this is called "hoisting"). His form is executed later, when the function expression is encountered in the step-by-step execution of the code.

Is there danger of him breaking my code by doing this?

Yes, this working code:

foo();
function foo() {
    // ...
}

...would break if rewritten as:

foo(); // <== Fails
var foo = function foo() {
    // ...
}

...because the function declaration hoisting is gone (var hoisting is still there), so the foo variable has the value undefined when you try to call it.

Separately, some browsers get NFEs wrong, creating two functions instead of one. IE8 does, for instance, as did older versions of Safari. All modern browsers I'm aware of get them right (now).

Finally, he's rewriting your code to rely on the horror that is Automatic Semicolon Insertion (to properly rewrite it, he'd need to be adding ; after the function body). ASI isn't perfect. Relying on it has also traditionally messed up minifiers, although these days most minifiers handle it properly (since technically, not handling it was a bug in the minifier).

Is one better practice than the other (can you cite any sources)?

That's a subjective matter of opinion, other than the real issues raised above (breaking due to removing hoisting, and NFEs).

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 2
    To share some subjective opinion: The function declaration is shorter, less redundant, and more distinctive. – Bergi Feb 24 '15 at 13:30
  • So it was just revealed to me that the motivation for using B is so that you can chain your function and variables in the following way. I've never written code like this. Is this a known approach? http://jsfiddle.net/s0vva8dm/1/ – Justice Gödel Conder Feb 24 '15 at 17:08
  • 1
    @JusticeGödelConder: There's no reason to do that in the example you've quoted. Function declarations would be clearer and less of a maintenance hassle. There's an argument for doing that if setting up a lot of functions as properties of an object (http://jsfiddle.net/s0vva8dm/2/), but that's not the same thing. And you wouldn't have been putting function declarations in the middle of an object initializer anyway; they wouldn't be valid there. – T.J. Crowder Feb 24 '15 at 17:59