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

Hi, I’m Abdul Samad. A web development learner and tech enthusiast. I write about what I learn, share practical coding tips, and publish in-depth blogs on programming and modern web development.
Check out my full collection of blogs on Hashnode: https://abdulsamad30.hashnode.dev/
Connect with me on X for quick updates and insights: @abdul_sama60108
If you've been learning JavaScript for a while, you've probably noticed that you're writing the same code over and over again.
Maybe you're calculating totals, validating user input, or formatting dates in multiple places.
That's where functions come in they're one of the most powerful tools in whole coding and js world.
What Functions Are and Why We Need Them
Think of a function as a recipe. When you want to bake a cake, you don't reinvent the process every time you follow the same set of steps.
Functions work the same way in programming. They're reusable blocks of code that perform a specific task.
Real-life analogy: Imagine you're a barista at a coffee shop. Instead of remembering the exact steps to make a cappuccino every single time someone orders one, you have a standard recipe you follow.
That recipe is like a function define it once, use it whenever needed.
Without functions, your code would be repetitive, harder to maintain, and honestly, exhausting to write. Here's what I mean:
// Without functions - repetitive code
let total1 = 50 + 30;
console.log("Total 1:", total1);
let total2 = 120 + 45;
console.log("Total 2:", total2);
let total3 = 200 + 75;
console.log("Total 3:", total3);
// With a function - clean and reusable
function addNumbers(a, b) {
return a + b;
}
console.log("Total 1:", addNumbers(50, 30));
console.log("Total 2:", addNumbers(120, 45));
console.log("Total 3:", addNumbers(200, 75));
Output:
Total 1: 80
Total 2: 165
Total 3: 275
Total 1: 80
Total 2: 165
Total 3: 275
The function approach is cleaner, easier to update, and if you need to change how addition works (maybe add logging or validation), you only change it in one place.
Function Declaration Syntax
Function declarations are probably the most straightforward way to create functions in JavaScript. You use the function keyword, give your function a name, and define what it should do.
Real-life analogy: It's like officially naming a family recipe. Once your grandmother writes down her secret cookie recipe and puts "Grandma's Chocolate Chip Cookies" at the top, everyone in the family can refer to it by name and make the exact same cookies.
Here's the syntax:
function greetUser(name) {
return "Hello, " + name + "! Welcome to JavaScript.";
}
// Calling the function
let message1 = greetUser("Sarah");
let message2 = greetUser("Mike");
console.log(message1);
console.log(message2);
Output:
Hello, Sarah! Welcome to JavaScript.
Hello, Mike! Welcome to JavaScript.
The structure is simple: function keyword, function name, parameters in parentheses, and the code block in curly braces. It's declarative you're declaring that this function exists and this is what it does.
Function Expression Syntax
Function expressions take a slightly different approach. Instead of declaring a function directly, you assign a function to a variable. It's still a function, but you're treating it like a value.
Real-life analogy: Instead of having a permanent sign that says "Grandma's Cookies Recipe" mounted on the kitchen wall, you write the recipe on a card and store it in your recipe box.
The recipe still exists and works the same way, but it's stored differently.
Here's how it looks:
const calculateArea = function(length, width) {
return length * width;
};
// Calling the function
let roomArea = calculateArea(12, 10);
let gardenArea = calculateArea(8, 6);
console.log("Room area:", roomArea, "sq ft");
console.log("Garden area:", gardenArea, "sq ft");
Output:
Room area: 120 sq ft
Garden area: 48 sq ft
Notice how we're assigning the function to a variable called calculateArea.
You still call it the same way, but behind the scenes, JavaScript treats it a bit differently.
Key Differences Between Declaration and Expression
While both get the job done, there are some important differences you should know about. Let's break them down with real scenarios that show when each approach shines.
Difference 1: Hoisting Behavior
This is the biggest practical difference. Let me show you with a shopping cart example:
// Declaration - works anywhere in the code
let price1 = calculateDiscount(100, 20); // Called BEFORE definition
let price2 = calculateDiscount(250, 15);
function calculateDiscount(price, discountPercent) {
return price - (price * discountPercent / 100);
}
console.log("Discounted Price 1:", price1);
console.log("Discounted Price 2:", price2);
// Expression - must be defined first
const applyTax = function(price, taxPercent) {
return price + (price * taxPercent / 100);
};
let finalPrice1 = applyTax(price1, 8); // Called AFTER definition
let finalPrice2 = applyTax(price2, 8);
console.log("Final Price 1:", finalPrice1);
console.log("Final Price 2:", finalPrice2);
Output:
Discounted Price 1: 80
Discounted Price 2: 212.5
Final Price 1: 86.4
Final Price 2: 229.5
Difference 2: Use in Callbacks and Event Handlers
Function expressions are perfect when you need to pass functions around as values.
Here's a real-world example with button clicks:
// Declaration - typically used for main utility functions
function validateEmail(email) {
return email.includes('@') && email.includes('.');
}
// Expression - perfect for event handlers and callbacks
const handleFormSubmit = function(email) {
if (validateEmail(email)) {
console.log("✓ Email is valid:", email);
return true;
} else {
console.log("✗ Email is invalid:", email);
return false;
}
};
// Simulating form submissions
handleFormSubmit("user@example.com");
handleFormSubmit("invalid-email");
Output:
✓ Email is valid: user@example.com
✗ Email is invalid: invalid-email
Difference 3: Array Methods and Functional Programming
When working with arrays, function expressions (especially arrow functions) feel more natural:
// Declaration - works but feels clunky with array methods
function doubleNumber(num) {
return num * 2;
}
let numbers = [1, 2, 3, 4, 5];
let doubledOldWay = numbers.map(doubleNumber);
// Expression - cleaner for inline operations
const tripleNumber = function(num) {
return num * 3;
};
let tripledNewWay = numbers.map(tripleNumber);
// Even better with inline expression
let quadrupled = numbers.map(function(num) {
return num * 4;
});
console.log("Original:", numbers);
console.log("Doubled:", doubledOldWay);
console.log("Tripled:", tripledNewWay);
console.log("Quadrupled:", quadrupled);
Output:
Original: [1, 2, 3, 4, 5]
Doubled: [2, 4, 6, 8, 10]
Tripled: [3, 6, 9, 12, 15]
Quadrupled: [4, 8, 12, 16, 20]
Difference 4: Conditional Function Creation
Function expressions let you create functions conditionally, which you can't do with declarations:
let userRole = "admin";
// This works with expressions
const getAccessLevel = userRole === "admin"
? function() { return "Full Access"; }
: function() { return "Limited Access"; };
console.log("User has:", getAccessLevel());
// Change role and recreate function
userRole = "guest";
const getGuestAccess = userRole === "guest"
? function() { return "Read Only"; }
: function() { return "No Access"; };
console.log("Guest has:", getGuestAccess());
Output:
User has: Full Access
Guest has: Read Only
Difference 5: Organizing Code in Objects
Function expressions are commonly used as methods in objects:
// Creating a shopping cart object
const shoppingCart = {
items: [],
addItem: function(item, price) {
this.items.push({ name: item, price: price });
console.log(`Added ${item} - $${price}`);
},
getTotal: function() {
let total = 0;
for (let item of this.items) {
total += item.price;
}
return total;
}
};
shoppingCart.addItem("Laptop", 999);
shoppingCart.addItem("Mouse", 25);
shoppingCart.addItem("Keyboard", 75);
console.log("Cart Total: $" + shoppingCart.getTotal());
Output:
Added Laptop - $999
Added Mouse - $25
Added Keyboard - $75
Cart Total: $1099
These differences really matter in real projects.
Function declarations are great for your main utility functions that you'll use throughout your code.
Function expressions shine when you're working with modern JavaScript patterns, callbacks, and need more flexibility in how you organize your code.
Basic Idea of Hoisting
Hoisting is one of those JavaScript quirks that can be confusing at first, but understanding it will save you from some head scratching bugs.
Real-life analogy: Imagine you're organizing a party.
With function declarations, it's like sending out invitations a week early everyone knows about the party before it happens.
With function expressions, it's like telling people about the party only on the day of they can't show up before you've announced it.
Here's what happens:
// This works! Function declaration is hoisted
console.log("Result 1:", addTwo(5, 3));
function addTwo(a, b) {
return a + b;
}
// This breaks! Function expression is NOT hoisted
console.log("Result 2:", subtractTwo(10, 4)); // Error!
const subtractTwo = function(a, b) {
return a - b;
};
Output:
Result 1: 8
TypeError: subtractTwo is not a function
JavaScript "hoists" function declarations to the top of their scope during the compilation phase.
This means you can use them before they appear in your code.
Function expressions, however, are treated like regular variable assignments they only exist from the point where you define them onwards.
When to Use Each Type
So when should you use declarations versus expressions? Both are valid, but here are some practical guidelines:
Use function declarations when:
You want the function available throughout your code, regardless of where you call it
You're writing helper utilities or core functions that other parts rely on
You want code that's easier to scan and understand at a glance
Use function expressions when:
You need to pass functions as arguments (callbacks)
You want to ensure functions are only available after they're defined
You're working with modern JavaScript patterns like arrow functions
You want to avoid potential hoisting confusion
Here's a practical scenario:
// Declaration - perfect for utility functions you'll use throughout
function formatCurrency(amount) {
return "$" + amount.toFixed(2);
}
// Expression - great for callbacks and specific contexts
const processPayment = function(amount, callback) {
console.log("Processing payment...");
let formatted = callback(amount);
console.log("Amount charged:", formatted);
};
// Using both together
processPayment(49.99, formatCurrency);
Output:
Processing payment...
Amount charged: $49.99
In modern JavaScript, you'll often see function expressions, especially with arrow functions, because they work really well with array methods, event handlers, and asynchronous code.
Practice Assignment
Ready to put this knowledge into practice? Here's a hands-on assignment:
Task 1: Write a function declaration that multiplies two numbers
function multiplyNumbers(num1, num2) {
}
Task 2: Write the same logic using a function expression
const multiplyNumbersExpr = function(num1, num2) {
return num1 * num2;
};
Task 3: Call both functions and print results
console.log("Declaration result:", multiplyNumbers(7, 8));
console.log("Expression result:", multiplyNumbersExpr(7, 8));
Task 4: Try calling them before defining and observe behavior
// Try this experiment:
console.log("Before definition:", multiplyNumbers(3, 4)); // Works!
console.log("Before definition:", multiplyNumbersExpr(3, 4)); // Error!
function multiplyNumbers(num1, num2) {
return num1 * num2;
}
const multiplyNumbersExpr = function(num1, num2) {
return num1 * num2;
};
Expected Output:
Before definition: 12
TypeError: multiplyNumbersExpr is not a function
This experiment clearly shows hoisting in action. Play around with this code, move things around, and see what breaks and what doesn't.
That's the best way to internalize these concepts.
Functions are the building blocks of any JavaScript application.
Whether you use declarations or expressions, understanding how they work and when to use each will make you a more confident developer.
Start simple, practice often, and soon you'll be writing clean, reusable code without even thinking about it.
FIN ✌️




