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

Functions are one of the most important building blocks in JavaScript. If you understand functions well, everything else (arrays, objects, async code, frameworks) gets much easier.

In this article, we’ll go from **what functions are** to **function declarations vs function expressions**, with **hoisting** explained in simple terms and **practical examples** you can try immediately.

## **What Is a Function and Why Do We Need It?**

A **function** is a **reusable block of code** that performs a specific task.

Instead of repeating the same code over and over, you:

*   Define it once as a function.
    
*   Call (or “invoke”) it whenever you need it.
    

### **Simple example: adding two numbers**

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

const result = add(3, 5);
console.log(result); // 8
```

Why this is useful:

*   **Reusability**: you can call `add(3, 5)`, `add(100, 25)`, etc.
    
*   **Organization**: complex logic can be broken into smaller named functions.
    
*   **Readability**: `add(price, tax)` It is easier to understand than **to do** `price + tax` everywhere.
    

## **Function Declaration Syntax**

A **function declaration** is the “classic” way to define a function in JavaScript.

Syntax:

```javascript
function functionName(parameter1, parameter2, ...) {
  // function body
  // optional: return something
}
```

### **Example: multiply two numbers:**

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

console.log(multiply(4, 6)); // 24
```

### **Key points:**

*   Starts with the `function` keyword.
    
*   Has a **name** (`multiply`).
    
*   Can have **parameters** (`a`, `b`).
    
*   Can be used `return` to send a value back.
    

### **Characteristics of function declarations**

*   **Named**: they always have a name.
    
*   **Hoisted**: You can call them **before** their definition in the code (we’ll explain hoisting soon).
    
*   Typically used for **top-level, reusable utilities** that you want available everywhere in a file.
    

## **Function Expression Syntax**

A **function expression** is when you create a function and **assign it to a variable**.

**Syntax:**

```javascript
const functionName = function(parameter1, parameter2, ...) {
  // function body
};
```

or with an anonymous function:

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

### **Example: multiply two numbers (function expression)**

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

console.log(multiply(4, 6)); // 24
```

Here:

*   `function(a, b) { ... }` is a **function expression**.
    
*   It has no name (this is an **anonymous function**).
    
*   It is assigned to a variable called `multiply`.
    

You can also use **arrow functions** (a more modern syntax), but we’ll stick to regular function expressions for clarity.

## **Function Declaration vs Function Expression (Side by Side)**

Let’s see the **same logic** written both ways.

### **Function declaration**

```javascript
function greet(name) {
  return `Hello, ${name}!`;
}

console.log(greet("Alice")); // "Hello, Alice!"
```

### **Function expression**

```javascript
const greet = function(name) {
  return `Hello, ${name}!`;
};

console.log(greet("Alice")); // "Hello, Alice!"
```

At **runtime**, once everything is defined, both work similarly:

*   You call them with `greet("Alice")`.
    
*   They return the same result.
    

The **big differences** are:

*   **How they are defined in the code (syntax)**.
    
*   How do they behave with **hoisting**?
    
*   How you use them in the **design and structure** of your code.
    

## **Key Differences: Declaration vs Expression**

Here’s a high-level comparison.

### **1\. Syntax and Style**

*   **Declaration**
    

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

*   **Expression**
    

```javascript
const add = function(a, b) {
  return a + b;
};
```

*   Declarations feel more “global” and top-level.
    
*   Expressions feel more “value-like”: a function as data assigned to a variable.
    

### **2\. Hoisting Behavior**

**Hoisting** is the JavaScript behavior where certain things are effectively “moved” to the top of their scope before the code runs.

At a very high level:

*   **Function declarations** are fully hoisted.
    
*   **Function expressions** (assigned to variables) are **not usable** before the line where they are defined.
    

We’ll show concrete examples in the hoisting section below.

* * *

### **3\. Naming and Flexibility**

*   **Declarations**: always named.
    
*   **Expressions**: can be anonymous or named.
    

This allows function expressions to be:

*   Passed as arguments to other functions.
    
*   Stored in objects or arrays.
    
*   Created conditionally.
    

Example: function expression as a callback

```javascript
setTimeout(function() {
  console.log("Executed later");
}, 1000);
```

Here we didn’t even save it to a variable—we just **used the function expression directly**.

### **4\. When You Might Prefer One Over the Other**

*   **Function declarations**:
    
    *   Good for **core utilities** and helpers.
        
    *   Good when you want functions available throughout the file.
        
    *   Good when readability is improved by seeing all the “main” functions at the top.
        
*   **Function expressions**:
    
    *   Good for **callbacks** (e.g., event handlers, array methods).
        
    *   Good when you want to **control the scope** and not pollute the global or outer scope with many names.
        
    *   Good when you treat functions like **values** (assign, pass around, etc.).
        

We’ll go deeper into “when to use which” later.

## **Hoisting: Simple, Practical Explanation**

Let’s keep hoisting **high-level and practical**, without going deeply into execution contexts or spec details.

### **The mental model**

You can think of JavaScript as doing two simple steps:

1.  **Setup phase**: It scans your code and:
    
    *   Registers **function declarations**.
        
    *   Reserves space for **variables**.
        
2.  **Execution phase**: It runs your code line by line.
    

Because of this:

*   You can call **function declarations** **before** their actual code appears.
    
*   But you **cannot** reliably use a **function expression** before the line where it’s defined.
    

### **Hoisting with Function Declarations**

You **can** do this:

```javascript
sayHello("Alice"); //  Works, even though sayHello is defined later

function sayHello(name) {
  console.log(`Hello, ${name}!`);
}
```

Why it works:

*   During the setup phase, JavaScript sees the function declaration `function sayHello(...) { ... }` and **registers** it.
    
*   When it starts executing line by line, `sayHello` it already exists.
    

### **Hoisting with Function Expressions**

You **cannot** safely do this:

```javascript
sayHello("Alice"); //  Error (or undefined), depending on how it's declared

const sayHello = function(name) {
  console.log(`Hello, ${name}!`);
};
```

Why it fails:

*   During setup, JavaScript **knows** there is a variable `sayHello`, but it does **not** yet assign the function to it.
    
*   At the time you call `sayHello("Alice")`, `sayHello` is not ready.
    
*   Result: you get an error like “Cannot access 'sayHello' before initialization” or similar.
    

Same idea with `let` or `var`, but details differ. The safe rule of thumb:

*\- Do not call function expressions before their line of definition.*

## **When to Use Function Declarations vs Function Expressions**

Both are valid and useful. The trick is **choosing based on intent and code organization**.

### **Use Function Declarations When…**

*   **You’re defining main utilities or core helpers** in a file.
    
*   You like having your **API-like functions** at the top of the file.
    
*   You want them to be **fully available anywhere** in that scope (because of hoisting).
    

Example: core helpers

```javascript
function calculateTotal(price, taxRate) {
  return price + price * taxRate;
}

function formatCurrency(amount) {
  return `$${amount.toFixed(2)}`;
}

// Usage below...
```

### **Use Function Expressions When…**

*   You’re defining functions **inside other functions**.
    
*   You’re using **callbacks** (e.g., `map`, `filter`, `setTimeout`, event handlers).
    
*   You want to **limit the scope** and avoid putting lots of function names in the outer level.
    
*   You’re building **objects or modules** where functions are **properties**.
    

Examples:

```javascript
// 1. Callback in array methods
const numbers = [1, 2, 3];

const doubled = numbers.map(function(n) {
  return n * 2;
});

// 2. Methods in an object
const calculator = {
  add: function(a, b) {
    return a + b;
  },
  multiply: function(a, b) {
    return a * b;
  }
};
```

## **Assignment Idea (Hands-On Practice)**

Here’s a small assignment you can try in a `.js` file or DevTools console.

### **1\. Function Declaration: multiply two numbers**

Write a **function declaration** that multiplies two numbers:

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

### **2\. Function Expression: same logic**

Write a **function expression** with the same logic:

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

### **3\. Call both functions and print the results**

```javascript
console.log("Declaration result:", multiplyDeclaration(3, 4)); // 12
console.log("Expression result:", multiplyExpression(3, 4));  // 12
```

### **4\. Try calling them BEFORE their definitions**

Now, let’s experiment with hoisting.

#### **Try this version:**

```javascript
console.log(multiplyDeclaration(2, 5)); // What happens?
console.log(multiplyExpression(2, 5));  // What happens?

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

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

What you should observe:

*   `multiplyDeclaration(2, 5)` **works**.
    
*   `multiplyExpression(2, 5)` **throws an error** (because the variable is not initialized yet at that point).
    

This small experiment makes hoisting very concrete.

## **Visual: Comparison Table (Declaration vs Expression)**

You can imagine/translate this into a diagram or table in your slides or notes.

| **Aspect** | **Function Declaration** | **Function Expression** |
| --- | --- | --- |
| Basic form | `function foo() { ... }` | `const foo = function() { ... };` |
| Name | Always has a name | Can be anonymous or named |
| Hoisting | Fully hoisted (can call before definition) | Not usable before the definition line |
| Common usage | Core helpers, top-level utilities | Callbacks, inline logic, assigning to variables/objects |
| Readability | Good for “API-like” public functions | Good for keeping related logic close to where it’s used |
| Flexibility as a value | Less obvious, but still a value | Very natural: it’s literally assigned to a variable |

## **Visual: Simple Execution Flow of a Function Call**

Here’s a conceptual, text-based “diagram” of a function call flow.

1.  **Your code**:
    

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

const result = add(2, 3);
console.log(result);
```

2.  **High-level flow**:
    

*   `add` is defined (either by declaration or expression).
    
*   You call `add(2, 3)`.
    
*   JavaScript:
    
    *   Takes `a = 2`, `b = 3`.
        
    *   Runs the function body.
        
    *   Reaches `return a + b`.
        
    *   Gives back `5`.
        
*   `result` becomes `5`.
    
*   `console.log(result)` prints `5`.
    

No need to think about execution contexts or call stacks at this stage—just follow **input → function → output**.

## **Summary**

*   Functions are **reusable blocks of code** that take input, optionally process it, and optionally return a result.
    
*   **Function declarations** use `function name(...) { ... }`, are **hoisted** and are great for **core helpers**.
    
*   **Function expressions** create functions as **values** and assign them to variables; they’re **not callable before their line**, and are perfect for **callbacks**, **inlining**, and **scoped utilities**.
    
*   **Hoisting (simple rule)**:
    
    *   You can call **function declarations** before they appear.
        
    *   You **should not** call **function expressions** before their line of definition.
        

If you internalize these ideas, you’ll have a solid foundation for understanding more advanced topics like:

*   Arrow functions
    
*   Methods in classes and objects
    
*   Closures and higher-order functions
    
*   Async functions and callbacks
    

*Happy coding!*
