Function Declaration vs Function Expression: What's the Difference?
Introduction
Imagine you have a recipe for making chai in your kitchen. Instead of writing down all the steps every time you want to make chai, you just follow the recipe. In programming, functions work the same way. They are reusable blocks of code that perform a specific task.
In JavaScript, there are two main ways to create functions: function declarations and function expressions. In this blog, we will learn what these are, how they differ, and when to use each one.
1. What Functions Are and Why We Need Them
A function is a block of code that performs a specific task. You write the code once and can use it many times without rewriting it.
Why Do We Need Functions?
Without functions, you would have to write the same code over and over again. This makes your code longer, harder to maintain, and more prone to errors.
Simple Analogy
Think of a function like an ATM machine:
You put in your card (input)
You enter your PIN
You request money
The machine gives you cash and a receipt (output)
Every time you use the ATM, you do not have to program it again. It performs the same task every time. Functions work the same way.
Basic Function Concepts
Before we learn about declaration and expression, let's understand some key terms:
Parameters: The variables listed when defining a function
function greet(name) { // "name" is a parameter
// Code to execute
}
Arguments: The values passed when calling a function
greet("Ashish"); // "Ashish" is an argument
Return Value: The value the function sends back
function add(a, b) {
return a + b; // "a + b" is the return value
}
2. Function Declaration Syntax
A function declaration is a way to define a function using the function keyword. It is the traditional way of creating functions in JavaScript.
Syntax
JavaScript
function functionName(parameter1, parameter2) {
// Code to execute
return result;
}
Simple Example 1: Adding Two Numbers
function addNumbers(a, b) {
return a + b;
}
let result = addNumbers(10, 20);
console.log(result); // Output: 30
Let's break this down:
functionis the keyword that says "I am declaring a function"addNumbersis the name of the functiona, bare parameters (placeholders for values)return a + bsends the result backaddNumbers(10, 20)calls the function with arguments 10 and 20
Multiple Statements in a Function
Functions can have multiple lines of code:
JavaScript
function calculateStudentGrade(marks) {
let grade;
if (marks >= 90) {
grade = "A";
} else if (marks >= 80) {
grade = "B";
} else if (marks >= 70) {
grade = "C";
} else {
grade = "F";
}
return grade;
}
console.log(calculateStudentGrade(85)); // Output: B
console.log(calculateStudentGrade(92)); // Output: A
Function with No Return Value
Some functions do not return anything. They just perform an action:
function printWelcome() {
console.log("Welcome to our college!");
}
printWelcome(); // Output: Welcome to our college!
3. Function Expression Syntax
A function expression is a way to define a function by assigning it to a variable. It is a more modern approach.
Syntax
const functionName = function(parameter1, parameter2) {
// Code to execute
return result;
};
Notice:
We use
constorletto create a variableThe function itself does not have a name (it is anonymous)
We end with a semicolon
;
Simple Example 1: Adding Two Numbers
const addNumbers = function(a, b) {
return a + b;
};
let result = addNumbers(10, 20);
console.log(result); // Output: 30
This does the same thing as the function declaration, but the syntax is different.
Function Expressions with let vs const
// Using const (recommended)
const multiply = function(a, b) {
return a * b;
};
// Using let
let divide = function(a, b) {
return a / b;
};
Both work, but const is recommended because you should not reassign a function to a different value.
4. Key Differences Between Declaration and Expression
Now let's compare function declarations and function expressions side by side.
Difference 1: Hoisting Behavior
This is the most important difference. Hoisting is when JavaScript moves declarations to the top of their scope before code runs.
Function declarations are hoisted completely. This means you can call them BEFORE they are defined:
// Calling the function BEFORE defining it
console.log(addNumbers(5, 10)); // Output: 15
// Function declaration
function addNumbers(a, b) {
return a + b;
}
This works! JavaScript hoists the entire function to the top, so it is available before the definition.
Function expressions are NOT hoisted. You cannot call them before they are defined:
// Calling the function BEFORE defining it
console.log(addNumbers(5, 10)); // Error: Cannot access 'addNumbers' before initialization
// Function expression
const addNumbers = function(a, b) {
return a + b;
};
This gives an error! The variable addNumbers is hoisted but not the function inside it.
Difference 2: Naming
Function declarations must have a name:
function addNumbers(a, b) { // "addNumbers" is the function name
return a + b;
}
Function expressions usually do not have a name (they are anonymous):
const addNumbers = function(a, b) { // The function itself has no name
return a + b;
};
However, function expressions CAN have a name (called named function expressions):
const addNumbers = function add(a, b) { // "add" is the function's name
return a + b;
};
console.log(addNumbers(5, 10)); // Works: 15
// console.log(add(5, 10)); // Error: add is not defined
Comparison Table
| Feature | Function Declaration | Function Expression |
|---|---|---|
| Syntax | function name() {} |
const name = function() {} |
| Must have a name | Yes | No (usually anonymous) |
| Can call before defining | Yes (hoisted) | No (Temporal Dead Zone) |
| Reassignable | Overwrites | Yes (with let), No (with const) |
| Use cases | General use | Callbacks, passing to other functions |
| Modern preference | Less common | More common |
5. Basic Idea of Hoisting (High Level)
Hoisting is JavaScript's behavior of moving declarations to the top of their scope before the code runs.
How Hoisting Works
JavaScript does two passes through your code:
Pass 1: Creation Phase
All function declarations are moved to the top and fully created
All variable declarations are noted but not assigned values (for
letandconst)
Pass 2: Execution Phase
Your code runs line by line
Variables get their values assigned
Simple Example
Let's see what happens with hoisting:
// This works even though greet is called before it is defined
console.log(greet("Ashish")); // Output: Hello, Ashish!
function greet(name) {
return "Hello, " + name + "!";
}
JavaScript internally rearranges it to:
// JavaScript moves the function to the top (hoisting)
function greet(name) {
return "Hello, " + name + "!";
}
// Your actual code runs here
console.log(greet("Ashish")); // Output: Hello, Ashish!
Function Expressions and Hoisting
Function expressions behave differently:
// This does NOT work
console.log(greet("Ashish")); // Error: Cannot access 'greet' before initialization
const greet = function(name) {
return "Hello, " + name + "!";
};
The variable greet is hoisted, but it is in the "Temporal Dead Zone" (TDZ) until the assignment happens. You cannot use it before it is defined.
Why This Matters
Hoisting can be confusing. This is why modern JavaScript developers:
Always define functions/variables before using them
Use function expressions with
constto avoid hoisting confusionUse tools like linters to catch these issues
6. When to Use Each Type
Use Function Declarations When
- You want the flexibility of calling before defining
// Works without issues
console.log(add(5, 10)); // Output: 15
function add(a, b) {
return a + b;
}
- You are writing simple, reusable utility functions
function calculateAge(birthYear) {
return new Date().getFullYear() - birthYear;
}
- You want clear, straightforward code
function validateEmail(email) {
return email.includes("@");
}
Use Function Expressions When
- You are assigning a function to a variable for specific use
const calculateTax = function(amount) {
return amount * 0.18;
};
- You are passing a function as an argument to another function
const numbers = [1, 2, 3, 4, 5];
// Functions can be passed as arguments
numbers.forEach(function(num) {
console.log(num);
});
- You want to ensure the function is not called before it is defined
const specialFunction = function() {
return "This function must be defined before use";
};
// Must call after definition only
specialFunction();
- You prefer modern JavaScript style
// Modern development tends to use function expressions
const greet = function(name) {
return "Hello, " + name;
};
Modern Best Practice
In modern JavaScript, function expressions with const are often preferred because:
They are not hoisted, which prevents accidental calls before definition
They are safer (cannot be reassigned if using
const)They are more explicit about when the function is available
Visual Execution Flow
Function Declaration Flow
JavaScript Starts
|
v
Hoisting Phase:
- Function declarations moved to top
- Function is fully created
|
v
Your Code Runs:
- Can call function anytime (before or after definition)
|
v
Function Call
|
v
Returns Result
Function Expression Flow
JavaScript Starts
|
v
Hoisting Phase:
- Variable is hoisted but not initialized
- Temporal Dead Zone starts
|
v
Your Code Runs:
- Cannot use variable in TDZ (error if accessed)
- Assignment happens, TDZ ends
- Now you can call the function
|
v
Function Call
|
v
Returns Result
Comparison Table Summary
| Aspect | Declaration | Expression |
|---|---|---|
| Definition | Using function keyword |
Using = with function |
| Example | function add(a, b) { return a + b; } |
const add = function(a, b) { return a + b; } |
| Hoisting | Fully hoisted, can call before defining | Not hoisted, Temporal Dead Zone |
| Name | Required | Usually not needed (anonymous) |
| Usage Before Definition | Works | Does not work (error) |
| Modern Preference | Less common | More common |
| Best For | Utility functions | Callbacks, modern code |
Summary
Functions are reusable blocks of code that perform specific tasks
Function declarations use the
functionkeyword and can be called before they are defined (hoisting)Function expressions assign a function to a variable and cannot be called before they are defined
Hoisting moves function declarations to the top, making them available everywhere
Temporal Dead Zone prevents function expressions from being called before they are defined
Use declarations for simple utility functions
Use expressions for modern code, callbacks, and when you want to prevent calling before definition
Best practice is to use function expressions with
constfor safer, more predictable code




