Function Declaration vs Function Expression: What’s the Difference?
A simple, visual guide for anyone learning JavaScript — no jargon, no confusion.
You’ve written your first few lines of JavaScript. You’ve seen function keyword everywhere. Then one day someone shows you this:
const greet = function() {
console.log("Hello!");
};And you think — wait, isn’t that just a function? Why is it assigned to a variable? Isn’t that wrong?
It’s not wrong. It’s a function expression — and it’s just as valid as the function you already know. But they behave differently in ways that will bite you if you don’t know the rules.
Let’s fix that.
First — why do functions exist at all?
Before we compare anything, let’s agree on the basics.
A function is a reusable block of code. Instead of writing the same logic five times in different parts of your program, you write it once, give it a name, and call it whenever you need it.
Think of it like a vending machine. You press a button (call the function), it does some work (runs the code), and it gives you something back (returns a value). You don’t need to know how the machine works inside — you just press the button.
// The "machine" — defined once
function addTwoNumbers(a, b) {
return a + b;
}// "Press the button" as many times as you want
console.log(addTwoNumbers(3, 5)); // 8
console.log(addTwoNumbers(10, 20)); // 30
console.log(addTwoNumbers(1, 1)); // 2Same logic. Written once. Used three times. That’s the whole point of functions.
Function declaration — the classic way
A function declaration is the most straightforward way to create a function. It starts with the function keyword, followed by a name, parentheses, and a body.
function multiply(a, b) {
return a * b;
}console.log(multiply(4, 5)); // 20That’s it. Clean. Readable. You declare a function called multiply, and now you can call it from anywhere in your code.
Anatomy of a function declaration
function multiply(a, b) {
// ↑ ↑ ↑ ↑
// keyword name parameters
return a * b;
// ↑
// return value
}Every part has a job:
The function keyword tells JavaScript you're about to define a function. The name (multiply) is how you'll call it later. The parameters (a, b) are the values you pass in — they work like local variables inside the function. return sends a value back to whoever called the function.
Function expression — the flexible way
A function expression also creates a function — but instead of declaring it standalone, you assign it to a variable.
const multiply = function(a, b) {
return a * b;
};console.log(multiply(4, 5)); // 20The output is identical. The logic is identical. The only difference is how you wrote it.
In a function expression, the function has no name of its own — it lives inside a variable. The variable multiply holds the function, and calling multiply(4, 5) is the same as pressing that vending machine button.
You can also write function expressions using arrow function syntax — a shorter, modern style:
const multiply = (a, b) => {
return a * b;
};// Even shorter for single-expression functions:
const multiply = (a, b) => a * b;console.log(multiply(4, 5)); // 20
Arrow functions are function expressions too — just written differently. Under the hood, they follow the same rules.
Side by side — the same logic, two ways
Here they are, directly compared:
// Function declaration
function multiply(a, b) {
return a * b;
}// Function expression
const multiply = function(a, b) {
return a * b;
};// Arrow function expression (same idea, shorter syntax)
const multiply = (a, b) => a * b;
All three produce the exact same result when you call multiply(4, 5). So why does the difference matter?
Two reasons: hoisting and when you can use them.
Hoisting — the key behavioural difference
Here’s the concept you need to understand. When JavaScript loads your file, before it runs a single line, it does a quick “scan” of the code. During this scan, it hoists (lifts) all function declarations to the top of their scope.
Get Chetan Chauhan’s stories in your inbox
Join Medium for free to get updates from this writer.
What this means in practice: you can call a function declaration before the line where you wrote it, and it still works.
// Calling BEFORE the definition — works fine!
console.log(multiply(3, 4)); // 12function multiply(a, b) {
return a * b;
}JavaScript saw the declaration during its scan, lifted it up, and made it available from the very start. This is hoisting.
Function expressions do not get hoisted. The variable is hoisted, but its value (the function) is not assigned until that line actually runs.
// Calling BEFORE the definition — crashes!
console.log(multiply(3, 4)); // TypeError: multiply is not a functionconst multiply = function(a, b) {
return a * b;
};JavaScript sees multiply exists (the variable is hoisted), but its value hasn't been assigned yet — so calling it throws an error.
Simple rule to remember: Declaration → hoist fully, call it anywhere. Expression → define it first, call it after.
Try it yourself — the assignment
Here’s a hands-on exercise to lock in the difference. Open your browser console or a code editor and try this:
Step 1 — Write both versions:
// Function declaration
function multiplyDeclaration(a, b) {
return a * b;
}// Function expression
const multiplyExpression = function(a, b) {
return a * b;
};Step 2 — Call both and log the results:
console.log(multiplyDeclaration(6, 7)); // 42
console.log(multiplyExpression(6, 7)); // 42Both give 42. So far, no difference.
Step 3 — Now try calling them BEFORE the definitions:
// Move these lines above your function definitions and observe:
console.log(multiplyDeclaration(6, 7)); // 42 — works!
console.log(multiplyExpression(6, 7)); // TypeError — crashes!This single experiment reveals everything. The declaration is available before it’s written. The expression is not. That’s hoisting in action.
When should you use each one?
Both are valid. Here’s how professionals think about it:
Reach for a function declaration when:
You’re writing a named, reusable utility that could be called anywhere in the file. The function is the “main thing” — not a helper being passed around.
// A utility that's called from many places
function formatCurrency(amount) {
return `₹${amount.toFixed(2)}`;
}Reach for a function expression when:
You’re passing the function as an argument to another function (callback), or you want to conditionally define it, or you want to prevent the function from being called before it’s ready.
// Callback — passed into another function
const numbers = [3, 1, 4, 1, 5];
const sorted = numbers.sort(function(a, b) { return a - b; });// Arrow expression — clean and concise for inline logic
setTimeout(() => {
console.log("This runs after 2 seconds");
}, 2000);// Conditional definition — expressions can do this, declarations cannot
let greet;
if (userLoggedIn) {
greet = function() { return "Welcome back!"; };
} else {
greet = function() { return "Hello, guest!"; };
}
The quick mental model
Think of a function declaration as a recipe card pinned to a board. Anyone can read it at any time — it’s always available, always named, always accessible before you cook anything.
Think of a function expression as a recipe written on a sticky note and placed inside a drawer. The drawer exists immediately (the variable), but the note is only inside after you put it there (after that line runs).
Both let you cook the same meal. The difference is when and how you can reach them.
Summary — everything at a glance
Function declaration Function expression Syntax function name() {} const name = function() {} Hoisting Fully hoisted — call anywhere Not hoisted — define first Name Always has a name Can be anonymous Best for Named utilities, general use Callbacks, inline logic, conditionals Arrow version Not applicable const name = () => {}
One last thought
Both styles are used in every real JavaScript codebase. You’ll see function declarations in utility files, and you’ll see arrow function expressions in React components, event handlers, and array methods every single day.
Understanding why they’re different — not just that they’re different — is what separates someone who copies code from someone who writes it confidently.
You now know the why. Go write some functions.
Found this helpful? Follow for more JavaScript fundamentals explained simply. And if you tried the assignment — share what happened when you called the expression before its definition. The error message is actually very informative once you know what to look for.
< Keep Coding / >



