Function Declarations vs Function Expressions in JavaScript

Every JavaScript developer writes functions constantly — but not everyone knows there are two distinct ways to define them, and that the difference actually matters. In this article, we'll break down both approaches clearly, compare them side by side, and help you know when to use which.
What Are Functions and Why Do We Need Them?
A function is a reusable block of code that performs a specific task. Instead of writing the same logic over and over, you write it once inside a function and call it whenever you need it.
// Without a function — repetitive ❌
console.log(5 + 3);
console.log(10 + 3);
console.log(22 + 3);
// With a function — clean and reusable ✅
function addThree(num) {
console.log(num + 3);
}
addThree(5); // 8
addThree(10); // 13
addThree(22); // 25
Functions make your code easier to read, maintain, and debug.
Function Declaration
A function declaration is the classic, straightforward way to define a function. You use the function keyword followed by a name.
function add(a, b) {
return a + b;
}
console.log(add(4, 6)); // 10
Syntax breakdown:
function functionName(parameters) {
// code to run
return value;
}
That's it. You declare it, you call it by name.
Function Expression
A function expression assigns a function to a variable. The function itself can be named or anonymous (no name).
const add = function(a, b) {
return a + b;
};
console.log(add(4, 6)); // 10
Syntax breakdown:
const functionName = function(parameters) {
// code to run
return value;
};
The result is the same — but how JavaScript treats these two behind the scenes is different.
Declaration vs Expression — Side by Side
// Function Declaration
function multiply(a, b) {
return a * b;
}
// Function Expression
const multiply = function(a, b) {
return a * b;
};
| Feature | Function Declaration | Function Expression |
|---|---|---|
| Syntax | function name() {} |
const name = function() {} |
| Hoisted? | Yes — usable before defined | No — must define before use |
| Has a name? | Always named | Usually anonymous |
Ends with ;? |
No semicolon needed | Semicolon at the end (it's a statement) |
| Best for | General reusable functions | Callbacks, conditional definitions |
Hoisting — The Simple Explanation
Hoisting is JavaScript's behavior of moving certain declarations to the top of their scope before the code runs.
Think of it like this: before your code actually executes, JavaScript does a quick scan and says "okay, what function declarations are here? I'll make note of them now."
Function declarations ARE hoisted
You can call a declared function before it appears in your code:
console.log(greet("Alice")); // "Hello, Alice!" ✅
function greet(name) {
return "Hello, " + name + "!";
}
JavaScript already knows about greet before it reaches that line.
Function expressions are NOT hoisted
console.log(greet("Alice")); // ❌ ReferenceError: Cannot access 'greet' before initialization
const greet = function(name) {
return "Hello, " + name + "!";
};
The variable greet exists, but it hasn't been assigned the function yet — so calling it early throws an error.
Simple mental model:
Your Code Runs...
↓
JavaScript scans first
↓
Function Declarations → loaded into memory ✅
Function Expressions → not yet, wait for their line ⏳
↓
Execution begins line by line
When to Use Each
Use a function declaration when:
You're writing a general-purpose, reusable utility function
You want flexibility to call it anywhere in the file
You want the code to be immediately readable and named clearly
function calculateTax(price, rate) {
return price * rate;
}
Use a function expression when:
You're passing a function as an argument (callback)
You want to conditionally define a function
You want to make it clear the function is tied to a specific variable
const double = function(n) {
return n * 2;
};
[1, 2, 3].map(double); // [2, 4, 6]
Both are valid — the best choice depends on your situation.
Putting It All Together
// Declaration — available anywhere in this scope
console.log(square(4)); // 16 ✅ (hoisted)
function square(n) {
return n * n;
}
// Expression — only available after this line
const cube = function(n) {
return n * n * n;
};
console.log(cube(3)); // 27 ✅
Practice Assignment
Work through these to lock in your understanding:
1. Write a function declaration that multiplies two numbers:
function multiply(a, b) {
return a * b;
}
console.log(multiply(4, 5)); // 20
2. Write the same logic as a function expression:
const multiplyExpr = function(a, b) {
return a * b;
};
console.log(multiplyExpr(4, 5)); // 20
3. Call both and confirm the results match:
console.log(multiply(3, 7)); // 21
console.log(multiplyExpr(3, 7)); // 21
4. Try calling them before defining — observe the difference:
// Try this and see what happens
console.log(multiply(2, 6)); // ✅ Works — declaration is hoisted
console.log(multiplyExpr(2, 6)); // ❌ Error — expression is not hoisted
function multiply(a, b) {
return a * b;
}
const multiplyExpr = function(a, b) {
return a * b;
};
What error do you get on the expression? That's hoisting in action.
Quick Recap
A function is a reusable block of code that runs when called
Function declarations use the
functionkeyword and a name — clean and straightforwardFunction expressions assign a function to a variable — flexible and powerful
Hoisting means declarations are available before their line in code; expressions are not
Use declarations for general utilities; use expressions for callbacks and conditional logic
Once you understand both, you'll write cleaner, more intentional JavaScript — and you'll never be caught off guard by a hoisting error again.
Happy coding! 🚀
If you enjoyed this article, check out my other blogs on this profile.
🔗 Connect with me:
LinkedIn | GitHub | X (Twitter)




