Function Declaration vs Function Expression in JavaScript: What’s the Difference?
If you’ve been learning JavaScript or preparing for technical interviews, you’ve probably encountered the question: What is the difference between a Function Declaration and a Function Expression in JavaScript?
Although both are used to define functions, they behave differently when it comes to hoisting, execution, scope, and real-world use cases. Choosing the right approach can improve your code’s readability, maintainability, and flexibility.
In this guide, you’ll learn the difference between function declaration and function expression in JavaScript, understand how hoisting affects each one, explore practical use cases, and discover why modern JavaScript often favors function expressions.
Table of Contents
What is a Function Declaration?
A Function Declaration defines a function using the function keyword followed by a function name.
Example:
function greet() {
console.log("Hello, World!");
}
Calling the function:
greet();
Output
Hello, World!
Function declarations are ideal for utility functions that are intended to be available throughout a file.
What is a Function Expression?
A Function Expression creates a function and assigns it to a variable.
Example:
const greet = function () {
console.log("Hello, World!");
};
Calling it:
greet();
Output
Hello, World!
Unlike function declarations, function expressions behave like variables.
The function isn’t available until the assignment executes.
Function Declaration vs Function Expression
Although the syntax looks similar, there are important differences.
| Feature | Function Declaration | Function Expression |
|---|---|---|
| Requires Function Name | Yes | Optional |
| Hoisted | Yes | No (only variable declaration is hoisted) |
| Callable Before Definition | Yes | No |
| Assigned to Variable | No | Yes |
| Common Use Cases | Utility functions | Callbacks, event handlers, dynamic logic |
The biggest practical difference is hoisting.
Hoisting: The Biggest Difference
Understanding hoisting is essential when comparing these two approaches.
Function Declaration Hoisting
Function declarations are fully hoisted.
This means you can call them before they appear in your code.
sayHello();
function sayHello() {
console.log("Hello!");
}
Output
Hello!
During compilation, JavaScript effectively makes the function available before execution begins.
Function Expression Hoisting
Function expressions behave differently.
sayHello();
const sayHello = function () {
console.log("Hello!");
};
Output
ReferenceError
Why?
Because only the variable declaration is hoisted—not its assigned value.
Until JavaScript executes:
const sayHello = function () { };
the variable remains in the Temporal Dead Zone (TDZ).
If you use var instead:
sayHello();
var sayHello = function () {
console.log("Hello!");
};
You’ll get:
TypeError: sayHello is not a function
Here’s what happens internally:
var sayHello = undefined;
sayHello();
Since undefined isn’t callable, JavaScript throws a TypeError.
Named vs Anonymous Function Expressions
Function expressions can be either anonymous or named.
Anonymous Function Expression
const add = function (a, b) {
return a + b;
};
Most callbacks are written this way.
Named Function Expression
const factorial = function calculate(n) {
if (n <= 1) {
return 1;
}
return n * calculate(n - 1);
};
Named function expressions are useful for recursion and debugging because stack traces display the function name.
Practical Use Cases
Understanding when to use each approach is more important than simply memorizing definitions.
Use Function Declarations When
- Creating reusable utility functions.
- Building helper methods.
- Defining functions that should be accessible throughout a module.
- Organizing business logic.
Example:
function calculateTax(price) {
return price * 0.18;
}
Use Function Expressions When
Function expressions are better suited for dynamic or contextual behavior.
Examples include:
- Event handlers
- Callback functions
- Conditional functions
- Factory functions
- Module patterns
Example:
button.addEventListener("click", function () {
console.log("Button clicked");
});
This function exists only where it’s needed.
Higher-Order Functions and Callbacks
One of the biggest reasons modern JavaScript prefers function expressions is callbacks.
Consider the map() method.
const numbers = [1, 2, 3];
const doubled = numbers.map(function (num) {
return num * 2;
});
Or using an arrow function:
const doubled = numbers.map(num => num * 2);
Function declarations don’t fit naturally here because the function is passed directly as an argument.
Similarly:
setTimeout(function () {
console.log("Done");
}, 1000);
This is another example where a function expression is the preferred choice.
Immediately Invoked Function Expressions (IIFE)
Before ES6 introduced block-scoped variables (let and const), developers often used Immediately Invoked Function Expressions (IIFEs) to create private scopes.
Example:
(function () {
console.log("Runs immediately");
})();
Output
Runs immediately
Why use an IIFE?
- Prevent global variable pollution.
- Create private variables.
- Execute initialization logic immediately.
Although ES6 reduced the need for IIFEs, you’ll still encounter them in older codebases and interview questions.
Can Function Expressions Be Assigned Conditionally?
Yes.
This is one area where function expressions are more flexible than declarations.
const greet = isMorning
? function () {
console.log("Good Morning");
}
: function () {
console.log("Good Evening");
};
You cannot conditionally declare functions as cleanly using function declarations.
Function Declaration vs Function Expression: Which Should You Use?
There isn’t a universally “better” choice.
Use Function Declarations when:
- The function is a reusable utility.
- You want the function available throughout the file.
- Readability is the priority.
Use Function Expressions when:
- Passing callbacks.
- Creating event handlers.
- Assigning functions dynamically.
- Building closures.
- Using IIFEs.
- Working with higher-order functions.
Modern JavaScript applications often use function expressions (and arrow functions) because they fit naturally with functional programming patterns.
Best Practices
When writing JavaScript:
- Prefer function declarations for reusable helper functions.
- Use function expressions for callbacks and dynamic behavior.
- Don’t rely on hoisting to improve readability.
- Declare functions before using them whenever possible.
- Use meaningful function names to improve debugging.
- Consider arrow functions when working with simple callbacks.
Frequently Asked Questions
What is the difference between function declaration and function expression?
A function declaration creates a named function that is fully hoisted, while a function expression creates a function that is assigned to a variable and becomes available only after the assignment executes.
Are function expressions hoisted?
Only the variable declaration is hoisted.
The assigned function is not available until JavaScript executes the assignment.
Which is better: function declaration or function expression?
Neither is universally better.
Use function declarations for reusable functions and function expressions for callbacks, event handlers, higher-order functions, and dynamic logic.
Can function expressions be anonymous?
Yes.
Many callbacks and event handlers use anonymous function expressions.
What is an Immediately Invoked Function Expression (IIFE)?
An IIFE is a function expression that executes immediately after it’s defined.
It was commonly used before ES6 to create private scopes.
Additional Learning Resources
Expand your JavaScript knowledge with these trusted resources:
- MDN Web Docs – Functions
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions - JavaScript.info – Functions
https://javascript.info/function-basics - ECMAScript Language Specification
https://tc39.es/ecma262/
Related Articles
If you’re exploring JavaScript fundamentals, these topics naturally complement this article:
- Difference Between
var,let, andconst - What Is Hoisting in JavaScript?
- Arrow Functions Explained
- Callback Functions in JavaScript
- Closures Explained
- Temporal Dead Zone (TDZ)
- Difference Between
==and===
Final Thoughts
Understanding the difference between function declaration and function expression in JavaScript is about more than syntax. It helps you understand how JavaScript executes code, how hoisting works, and why certain patterns are preferred in modern development.
As a general guideline:
- Choose function declarations for reusable, standalone functions.
- Choose function expressions when passing callbacks, handling events, creating closures, or assigning behavior dynamically.
As you become more comfortable with JavaScript, you’ll notice that both approaches have their place. The key is understanding their behavior so you can choose the one that best fits your use case.
Mastering this concept will not only improve your JavaScript skills but also prepare you for one of the most frequently asked frontend interview questions.