Function Declaration vs Function Expression: What’s the Difference?

What Functions Are and Why We Need Them
A function is a reusable block of code — write the logic once, and run it as many times as needed, with different inputs, instead of repeating the same code over and over.
function add(a, b) {
return a + b;
}
add(2, 3); // 5
add(10, 20); // 30Without functions, every calculation like this would need its own separately written code, every single time it’s needed — functions let you write the logic once and simply call it whenever it’s needed again.
Function Declaration Syntax
A function declaration is the traditional, most familiar way to define a function — using the function keyword, followed directly by a name:
function multiply(a, b) {
return a * b;
}
multiply(4, 5); // 20The key identifying feature: it starts with function, has a name right after it, and stands on its own as a complete statement — not assigned to a variable.

Function Expression Syntax
A function expression defines a function as part of a larger expression — most commonly, by assigning it to a variable:
const multiply = function (a, b) {
return a * b;
};
multiply(4, 5); // 20Notice the function itself here has no name after the function keyword (it's anonymous) — instead, it's assigned to the variable multiply, which is how it gets called later.
Function expressions can also use arrow function syntax (covered in depth in this series’s dedicated article on arrow functions):
const multiply = (a, b) => a * b;
Key Differences Between Declaration and Expression
// Function Declaration
function multiply(a, b) {
return a * b;
}
// Function Expression
const multiply = function (a, b) {
return a * b;
};
Both versions above behave identically when called — multiply(4, 5) returns 20 either way. The real differences are structural and behavioral, not about what the function actually does:


Basic Idea of Hoisting (Very High Level)
Hoisting is JavaScript’s behavior of processing certain declarations before actually running the code line by line — and it affects function declarations and function expressions very differently.
Function declarations are hoisted completely
console.log(multiply(4, 5)); // 20 — works, even though it's called before the definition appears below
function multiply(a, b) {
return a * b;
}
This works because JavaScript processes the entire function declaration — name and body — before running the rest of the code. By the time multiply(4, 5) is actually called, the function is already fully available, regardless of where it's physically written in the file.
Function expressions are not hoisted the same way
console.log(multiply(4, 5)); // Error! Cannot access 'multiply' before initialization
const multiply = function (a, b) {
return a * b;
};
Here, multiply is a variable, and while the variable's existence is hoisted, its value (the actual function) isn't assigned until that line of code actually runs. Calling it before that assignment happens results in an error — the function simply isn't usable yet.

The simple, practical takeaway: function declarations can be called before they appear in your file; function expressions cannot be called until the line defining them has actually executed.
When to Use Each Type
Use a function declaration when:
- You want a function usable throughout the file, regardless of where it’s defined relative to where it’s called
- You’re defining a clearly named, standalone utility function
- You want the traditional, most immediately readable syntax for a named function
Use a function expression when:
- You want to control precisely when a function becomes available (only after its specific line runs)
- You’re assigning a function conditionally, or as a value inside another structure (like an object property or a callback passed into another function)
- You’re using arrow function syntax for a shorter, inline function
// A common function expression use case: passing a function as a callback
button.addEventListener("click", function () {
console.log("Clicked!");
});

Neither is strictly “better” — they’re suited to different situations, and most real codebases use both, depending on the specific need at each point in the code.
Practice Assignment
1. Write a function declaration that multiplies two numbers
function multiplyDeclaration(a, b) {
return a * b;
}2. Write the same logic using a function expression
const multiplyExpression = function (a, b) {
return a * b;
};3. Call both functions and print results
console.log(multiplyDeclaration(6, 7)); // 42
console.log(multiplyExpression(6, 7)); // 42
4. Try calling them before defining, and observe behavior
console.log(multiplyDeclaration(2, 3)); // 6 — works fine!
function multiplyDeclaration(a, b) {
return a * b;
}
console.log(multiplyExpression(2, 3)); // Error: Cannot access 'multiplyExpression' before initialization
const multiplyExpression = function (a, b) {
return a * b;
};
Run both versions yourself and observe the difference directly — seeing the function declaration succeed and the function expression fail, side by side, is a fast, reliable way to make this distinction genuinely stick.
Final Takeaway
Function declarations and function expressions can do exactly the same job — the difference is entirely in how they’re written, and when they actually become usable. A function declaration is a complete, named statement, fully available throughout the file the moment it’s hoisted. A function expression is a value, assigned to a variable, only usable from the point that assignment actually runs. Neither is a “better” choice universally — declarations suit standalone, broadly-used functions; expressions suit functions passed around, assigned conditionally, or defined inline. Once the hoisting difference clicks, choosing between them becomes a matter of what the specific situation actually calls for, not a rule to memorize blindly.
Frequently Asked Questions
Can a function expression ever be named?
> Yes — const multiply = function multiplyNumbers(a, b) { ... } is a named function expression. The name (multiplyNumbers) is mainly useful for debugging (showing up in stack traces) and isn't accessible outside the function itself the way the variable (multiply) is.
Why does hoisting behave differently for declarations vs expressions?
> Function declarations are processed completely — including their full body — before the rest of the code runs. Function expressions are really variable assignments, and only the variable’s existence (not its assigned value) is hoisted, which is why the function itself isn’t usable until that specific line actually executes.
Does using let or const instead of var change how function expressions are hoisted?
> The underlying hoisting behavior of the function expression itself stays the same either way. let and const do add their own protection (throwing a clear error if accessed too early) compared to var, which would instead silently give undefined — but in both cases, the actual function isn't usable until its assignment line runs.
Is one of these considered more “modern” than the other?
> Not really — both remain widely used today. Arrow function expressions have become especially popular for short, inline functions, but traditional function declarations are still completely standard for larger, standalone, named functions.
Originally published by Mr Madhukar
Read the complete article on Medium with full formatting & reader responses.