The two notations are functionally equivalent.
You can assume that:
function a() {}
function b() {}
is interpreted as:
var a, b;
a = function a() {};
b = function b() {};
This is why you don't have to declare- (not define!) before-use. You can reassign functions after you've defined them, just like you would with a variable. Functions get hoisted just like variables, because they are variables (mind=blown? good!).
Declare-before-use
function a() { b(); } // using b before it's declared?
function b() {}
becomes:
var a, b;
a = function a() { b(); }; // nope! b is declared, we're good
b = function b() {};
Redefining a function
function a() { alert("a"); }
a = function b() { alert("b"); }; // that's weird!
becomes:
var a;
a = function a() { alert("a"); };
a = function b() { alert("b"); }; // oh, that looks normal
Declare vs define
Declare is: var x
. In English: "I will be using variable x
".
Define is: x = 5
. In English "Variable x
now has the value 5
".
Declare-before-use is required and enforced in "use strict"
. Define-before-use is not required. If your variables are defined in run-time you're good.
So var x = 5
is both a declaration and a definition, as is function a() {}
.
Be cautious when naming functions not to override an existing variable:
var a = function () { alert("a"); };
var b = function a() { alert("b"); };
a(); // prints "b"
Lint tools will pick up on this.
When to use which notation?
I would recommend using the function expression notation (var a = function () {}
) only when you are reassigned the value of a
later on. The function expression then signals to the reader that a
is going to get reassigned and that it is intentional.
Another (minor) argument for the function expression notation is a Lint tool like JSLint that might require you to declare (not define!) your functions before you use them. If you have functions with a recursive definition, ie. a
calls b
and b
calls a
, you can not declare one before the other by using the function declaration notation.
Edit notes: I've made a slight revision about named anonymous functions. It can be usefull to name anonymous functions when you're looking at a stacktrace. The named function will give more context lest it be logged as 'anonymous'.