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).