JavaScript: Difference Between Function Declaration vs Function Expression
When you use the keyword function
to define function, there are many complex issues about name-hosting and nesting functions.
const g = function f() { return 3; }; console.log(f() === 3); /* error: Uncaught ReferenceError: f is not defined */
When is Function Definition a Declaration?
It is a function declaration if all of the following are met:
- At top-level of source code (that is, not inside any curly bracket.) or it is at top-level inside a function, it is called Function Declaration.
- Not on the right-hand-side of a assignment.
/* Function Declaration */ function f() { return 3; } console.log(f() === 3);
Function Declaration Must be Top Level
Named function form is a declaration only if it is at top level of source code or top level inside a function body. When in elsewhere, its a named function expression.
const g = function f() { return 3; }; /* no function declaration happens here. The f is treated as named function expression */ console.log(f() === 3); /* error: Uncaught ReferenceError: f is not defined */
/* [ error: Uncaught ReferenceError: Cannot access 'h' before initialization ] */ h(); const h = function h() { return 3; };
/* [ error: Uncaught ReferenceError: bb is not defined ] */ bb(); const aa = function bb() { return 3; };
/* [ error: Uncaught ReferenceError: bb is not defined ] */ const aa = function bb() { return 3; }; bb();
When is Function Expression
When you have this:
function name (params) {body}
or
function (params) {body}
and it is not at top-level of source code, nor at top-level inside a function, it has meaning of Function Expression.
// function expression, applied on the spot console.log( (function () { return 3; })() === 3, );
// function expression with one parameter, applied on the spot console.log( (function (x) { return x; })(4) === 4, );
You can assign a function to a variable. In effect, giving the function a name.
/* give a function expression a name */ const g = function () { return 3; }; console.log(g() === 3);