JavaScript: What's the Difference Between Function Declaration and Function Expression

, , …,
Want to master JavaScript in a week? Buy Xah JavaScript Tutorial.

What's the difference between function declaration and function expression?

function f () {};

and

var f = function () {};

Function Declaration → Hoisting Name & Value

Function declaration will hoist the function name and definition to the top, but function expression assigned to variable will only hoist the name, not the definition.

Compare:

// works
f(); // ⇒ 3
function f () {return 3;};
// TypeError: undefined is not a function
g();
var g = function () {return 3;};

Function Declaration Must be Top Level

// function declaration only happens as top level of source code or top level of function body.
// when in elsewhere, its function expression

var g = function f() { return 3; } // no function declaration happens here

g(); // returns 3

f(); // ReferenceError: f is not defined
// TypeError: undefined is not a function
h();
var h = function h () {return 3;};
// ReferenceError: bb is not defined
bb();
var aa = function bb () {return 3;};
// ReferenceError: bb is not defined
var aa = function bb () {return 3;};
bb();

The technical detail is fairly complicated. See: 〔Named function expressions demystified By Juriy “Kangax” Zaytsev. @ http://kangax.github.io/nfe/

Thanks to ЮрийТарабанько and Paul Oldridge.

Summary of What Should You Do?

• Good: Use function declaration function name() { … } at top level of your source code or top level of function body as inner function.

// function in top level source code
function f() {
    // something
}
function f() {

    // code

    // function in top level inside function body
    function g() {
        // something
    }

    // code. call g somewhere here

}

• Good: Use function expression var f = function () {…};.

// this is good
var f = function () {  
    // };

• function “declaration” should not be used as expression or statement inside expression or statement.

// never do this. (some browser may support it)
if ( x ) {
    function f() { … }
}

• Avoid named function expression:

// don't do this
var f = function g() {
    // };

// don't do this
var f = function f() {
    // };
blog comments powered by Disqus