Function Declaration vs Function Expression in JS
In JavaScript, functions can be defined primarily using function declarations or function expressions. While both achieve the goal of executing reusable blocks of code, they differ significantly in their syntax, how the JavaScript engine loads them into memory through hoisting, when they are evaluated, and their suitability for different programming patterns like callbacks and closures.
Syntax Differences
A function declaration is a standalone statement
that begins with the function keyword and must include an
identifier (the function’s name).
function greet() {
return "Hello, World!";
}A function expression defines a function as part of a larger expression, typically by assigning it to a variable. These can be anonymous (without a name) or named, and they can also be written using arrow function syntax.
// Anonymous function expression
const greet = function() {
return "Hello, World!";
};
// Named function expression
const greetNamed = function greetMessage() {
return "Hello, World!";
};
// Arrow function expression
const greetArrow = () => "Hello, World!";Key Differences
1. Hoisting Behavior
The most critical technical distinction between the two is hoisting.
- Function Declarations: The entire function definition is hoisted to the top of the enclosing scope during the compilation phase. This means you can invoke the function before its declaration appears in the code.
sayHello(); // Output: "Hello!"
function sayHello() {
console.log("Hello!");
}- Function Expressions: Only the variable declaration
is hoisted, not the function assignment. If declared with
var, the variable initializes asundefined, resulting in aTypeErrorif called before assignment. If declared withletorconst, it remains in the Temporal Dead Zone (TDZ), causing aReferenceError.
sayGoodbye(); // ReferenceError: Cannot access 'sayGoodbye' before initialization
const sayGoodbye = function() {
console.log("Goodbye!");
};2. Execution and Evaluation Timing
- Declarations are evaluated before any code is executed.
- Expressions are evaluated only when the execution flow reaches that specific line of code.
3. Conditional Declarations
Function expressions provide greater flexibility when creating functions conditionally.
let logMessage;
if (isProduction) {
logMessage = function(msg) { /* silent or production log */ };
} else {
logMessage = function(msg) { console.log(msg); };
}While modern JavaScript allows function declarations inside block scopes, behavior can vary depending on strict mode and may lead to inconsistent results across different JavaScript environments.
4. Immediately Invoked Function Expressions (IIFE)
Function expressions can be executed immediately after they are defined, which is useful for creating private scopes. Function declarations cannot be immediately invoked in this manner without syntax errors.
(function() {
const privateVar = "Secret";
console.log("Executed immediately");
})();When to Use Each
- Use Function Declarations for main utility functions or top-level logic where you want broad accessibility within a module or script, regardless of where the function is written in the file.
- Use Function Expressions when passing functions as arguments (callbacks), assigning functions dynamically, writing modular code using arrow functions, or limiting the availability of a function to a specific point in the runtime execution.