Skip to main content

Command Palette

Search for a command to run...

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

Published
10 min read

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:

  • function is the keyword that says "I am declaring a function"

  • addNumbers is the name of the function

  • a, b are parameters (placeholders for values)

  • return a + b sends the result back

  • addNumbers(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 const or let to create a variable

  • The 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 let and const)

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:

  1. Always define functions/variables before using them

  2. Use function expressions with const to avoid hoisting confusion

  3. Use tools like linters to catch these issues


6. When to Use Each Type

Use Function Declarations When

  1. 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;
}
  1. You are writing simple, reusable utility functions
function calculateAge(birthYear) {
  return new Date().getFullYear() - birthYear;
}
  1. You want clear, straightforward code
function validateEmail(email) {
  return email.includes("@");
}

Use Function Expressions When

  1. You are assigning a function to a variable for specific use
const calculateTax = function(amount) {
  return amount * 0.18;
};
  1. 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);
});
  1. 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();
  1. 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:

  1. They are not hoisted, which prevents accidental calls before definition

  2. They are safer (cannot be reassigned if using const)

  3. 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

  1. Functions are reusable blocks of code that perform specific tasks

  2. Function declarations use the function keyword and can be called before they are defined (hoisting)

  3. Function expressions assign a function to a variable and cannot be called before they are defined

  4. Hoisting moves function declarations to the top, making them available everywhere

  5. Temporal Dead Zone prevents function expressions from being called before they are defined

  6. Use declarations for simple utility functions

  7. Use expressions for modern code, callbacks, and when you want to prevent calling before definition

  8. Best practice is to use function expressions with const for safer, more predictable code