What is the difference between function declaration and expression?
In JavaScript, functions are a fundamental building block. There are two primary ways to define a function: as a function declaration or as a function expression. While both achieve the goal of creating a callable function, they have distinct syntactic forms and behavioral differences, especially concerning hoisting.
Function Declaration
A function declaration (also known as a function statement) defines a named function. It is defined using the function keyword, followed by the function's name, a list of parameters, and the function body enclosed in curly braces. A key characteristic of function declarations is that they are hoisted. This means that the function can be called even before it is defined in the code, as its definition is moved to the top of the current scope during the compilation phase.
hoistedFunction(); // This works due to hoisting
function hoistedFunction() {
console.log("I am a hoisted function declaration.");
}
hoistedFunction();
Function Expression
A function expression defines a function as part of an expression. This often involves assigning an anonymous function to a variable, though it can also be a named function expression. Unlike declarations, function expressions are not hoisted in the same way. Only the variable name is hoisted (with an undefined value), not the function definition itself. Therefore, you cannot call a function expression before its definition in the code, as the variable will not yet hold the function value. Function expressions are frequently used as arguments to other functions (callbacks), immediately invoked function expressions (IIFEs), or for creating closures.
// unhoistedFunction(); // This would throw a TypeError: unhoistedFunction is not a function
const unhoistedFunction = function() {
console.log("I am a function expression.");
};
unhoistedFunction();
// A named function expression (less common, but useful for recursion within the function)
const namedExpression = function myNamedFunc() {
console.log("I am a named function expression.");
// myNamedFunc is accessible only within this function scope
};
namedExpression();
Key Differences Summarized
| Feature | Function Declaration | Function Expression |
|---|---|---|
| Syntax | `function name(...) { ... }` | `const name = function(...) { ... };` or `const name = () => { ... };` |
| Hoisting | Fully hoisted (function available before definition) | Variable declaration is hoisted, but function assignment is not (TypeError if called before definition) |
| Naming | Always has a name | Can be anonymous (`function()`) or named (`function myFunc()`) but the name is usually only accessible within the function itself. |
| Semicolon | No semicolon needed at the end of the block (though not an error if present) | Semicolon is generally required at the end of the assignment statement |
| Use Cases | General-purpose functions, defining global or module-scoped functions | Callbacks, IIFEs, closures, assigning functions conditionally, or as method properties of objects |