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

*By Saurabh Prajapati | IBM Software Engineer | WebDev Cohort 2026*

* * *

## Why I Wanted to Explore This

When I first started writing JavaScript, I would just write functions like this and move on:

```javascript
function greet() {
  console.log("Hello!");
}
```

Simple enough, right? But then I started seeing code like this all over the place:

```javascript
const greet = function() {
  console.log("Hello!");
}
```

Wait... aren't these doing the same thing? Why would anyone write it differently?

Let me walk you through everything I discovered.

* * *

## First, What Even Is a Function?

Before we compare, let's get on the same page.

A **function** is just a reusable block of code. Instead of writing the same logic again and again, you wrap it in a function and call it whenever you need it.

Think of it like a recipe. You write the steps once, and then you can "use" that recipe anytime you want to cook that dish.

Here's the simplest example:

```javascript
function addNumbers(a, b) {
  return a + b;
}

console.log(addNumbers(3, 5)); // Output: 8
console.log(addNumbers(10, 20)); // Output: 30
```

You write the logic once. You reuse it everywhere. That's the power of functions.

* * *

## Function Declaration

This is the classic way. You've probably seen it a hundred times.

```javascript
function multiply(a, b) {
  return a * b;
}

console.log(multiply(4, 5)); // Output: 20
```

The syntax is straightforward:

*   Start with the `function` keyword
    
*   Give it a name (`multiply`)
    
*   Define the parameters inside `()`
    
*   Write the logic inside `{}`
    

That's it. Clean, simple, readable.

* * *

## Function Expression

Now here's where it gets interesting.

In a **function expression**, you create a function and **assign it to a variable**.

```javascript
const multiply = function(a, b) {
  return a * b;
};

console.log(multiply(4, 5)); // Output: 20
```

Notice what changed:

*   No function name after the `function` keyword (this is called an **anonymous function**)
    
*   The function is stored inside a `const` variable called `multiply`
    
*   There's a `;` at the end (because it's a variable assignment)
    

The result is the same. But how JavaScript *treats* these two approaches behind the scenes? Very different.

* * *

## Side-by-Side Comparison

Here's a quick visual to make it stick:

```plaintext
┌─────────────────────────────────┬─────────────────────────────────────┐
│      Function Declaration       │        Function Expression          │
├─────────────────────────────────┼─────────────────────────────────────┤
│ function greet() { ... }        │ const greet = function() { ... };   │
├─────────────────────────────────┼─────────────────────────────────────┤
│ Has a name always               │ Usually anonymous                   │
├─────────────────────────────────┼─────────────────────────────────────┤
│ Hoisted (can call before it's   │ NOT hoisted (must define first,     │
│ defined)                        │ then call)                          │
├─────────────────────────────────┼─────────────────────────────────────┤
│ Great for utility functions     │ Great for callbacks, passing        │
│ used everywhere                 │ functions around                    │
├─────────────────────────────────┼─────────────────────────────────────┤
│ Defined at parse time           │ Defined at runtime                  │
└─────────────────────────────────┴─────────────────────────────────────┘
```

* * *

## The Big Difference: Hoisting

Okay, this is the part that tripped me up the most. Let me explain it simply.

**Hoisting** means JavaScript reads through your code before running it and "moves" certain things to the top. Not literally — but it *behaves* that way.

### Function Declarations Are Hoisted ✅

```javascript
// Calling BEFORE the function is defined
console.log(greet()); // Output: "Hello!"

function greet() {
  return "Hello!";
}
```

Wait — how did this work? We called `greet()` *before* we even wrote the function!

That's hoisting. JavaScript saw the function declaration, mentally "lifted" it to the top, and made it available everywhere in the file.

### Function Expressions Are NOT Hoisted ❌

```javascript
// Calling BEFORE the function expression is defined
console.log(greet()); // ❌ Error: Cannot access 'greet' before initialization

const greet = function() {
  return "Hello!";
};
```

This throws an error. Because `greet` is just a variable here. And variables declared with `const` or `let` are not available before their line in the code.

I made this mistake early on. I was confused why one worked and the other didn't. Now I know exactly why.

> **Key rule to remember:**
> 
> *   Function declaration → Call it anywhere in the file ✅
>     
> *   Function expression → Must define it first, then call ✅
>     

* * *

## When Should You Use Each One?

Honestly, this is a judgment call. But here's how I think about it:

**Use Function Declaration when:**

*   The function is a general utility used across many places
    
*   You want the flexibility to call it anywhere in your file
    
*   You're defining named, standalone functions
    

```javascript
// Good use of declaration - utility function used everywhere
function formatDate(date) {
  return new Date(date).toLocaleDateString();
}
```

**Use Function Expression when:**

*   You're passing a function as an argument (callback)
    
*   You want to conditionally define a function
    
*   You're using arrow functions (a modern form of expression)
    

```javascript
// Good use of expression - passing as a callback
const numbers = [1, 2, 3, 4];
const doubled = numbers.map(function(num) {
  return num * 2;
});

console.log(doubled); // [2, 4, 6, 8]
```

* * *

## A Quick Look at Arrow Functions (Bonus)

You've probably seen this syntax too:

```javascript
const multiply = (a, b) => a * b;

console.log(multiply(3, 4)); // Output: 12
```

Arrow functions are a **shorter form of function expressions**. They're very popular in modern JavaScript.

Same rules apply — they are NOT hoisted.

* * *

## Assignment: Try It Yourself

Here's a small challenge to solidify your understanding:

### Step 1 — Write a Function Declaration

```javascript
function multiplyDeclaration(a, b) {
  return a * b;
}

console.log(multiplyDeclaration(6, 7)); // Expected: 42
```

### Step 2 — Write the Same as a Function Expression

```javascript
const multiplyExpression = function(a, b) {
  return a * b;
};

console.log(multiplyExpression(6, 7)); // Expected: 42
```

### Step 3 — Try Calling Before Defining

```javascript
// Test hoisting behavior

console.log(multiplyDeclaration(3, 3)); // ✅ Works — 9
console.log(multiplyExpression(3, 3)); // ❌ Error — try it!

function multiplyDeclaration(a, b) {
  return a * b;
}

const multiplyExpression = function(a, b) {
  return a * b;
};
```

Run this in your browser console or Node.js. See the error with your own eyes. That experience will make hoisting click better than any explanation.

* * *

## What I Wish I Knew Earlier

A few quick "I wish I knew this" moments:

*   **The name on a function expression is optional** — but you *can* name it for better stack traces in errors
    
*   **Arrow functions are expressions too** — same hoisting rules apply
    
*   `var` **behaves differently** from `const`/`let` with hoisting — but that's a rabbit hole for another day
    
*   **Most modern codebases use both** — don't feel like you have to pick just one
    

* * *

## Key Takeaways

Let's wrap up what we covered:

*   A **function** is a reusable block of code
    
*   **Function declaration** uses the `function` keyword with a name — hoisted ✅
    
*   **Function expression** assigns a function to a variable — not hoisted ❌
    
*   Use declarations for general-purpose utilities
    
*   Use expressions for callbacks and dynamic logic
    
*   Arrow functions are a modern shorthand for expressions
    

* * *

## About the Author

**Saurabh Prajapati** is a Full-Stack Software Engineer at IBM India Software Lab, working on enterprise-level cloud-native solutions using Maximo. He specializes in GenAI, React, and modern web technologies, and loves sharing his learning journey with other developers.

*   🐙 GitHub: [prajapatisaurabh](https://github.com/prajapatisaurabh)
    
*   💼 LinkedIn: [saurabh-prajapati](https://linkedin.com/in/saurabh-prajapati)
    
*   📧 [saurabhprajapati120@gmail.com](mailto:saurabhprajapati120@gmail.com)
