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


## What functions are and why we need them ?

### What functions are ?

Functions are reusable blocks of code that perform a specific task. They help organize code, prevent repetition, and make programs easier to read and maintain. Functions are considered "first-class citizens," meaning they are treated like any other value (e.g., numbers, strings), so they can be assigned to variables, passed as arguments, and returned by other functions.

**Ways to Define Functions:-**

**Function Declaration**: The standard way, using the `function` keyword followed by a name. These are hoisted, meaning they can be called before they appear in the code.

**Function Expression**: A function created as a value and assigned to a variable. Function expressions are not hoisted in the same way as declarations.

**Arrow Functions**: A concise syntax (introduced in ES6) for writing function expressions, often used for short, simple functions. They have some limitations, such as not having their own `this` binding.

### Why we need them ?

Functions are essential because they allow developers to structure , organize and manage code effectively. They are the main "building blocks" of programs and offer significant advantages for writing efficient and maintainable software.

The primary reasons for using functions:-

**Code Reusability Modularity and Organization Readability and Clarity Easier Debugging Encapsulation Abstraction Flexibility**

## Function declaration syntax

**Function Declaration**

This is the traditional and most common way to define a named function. Function declarations are hoisted, meaning they can be called before they are defined in the code.

Example:-

`function add(a, b) {`

`return a + b;`

`}`

`console.log(add(5, 3));` // Output: 8

## Function expression syntax

**Function Expression**

A function expression creates a function as a value, which is then typically assigned to a variable. These functions are not hoisted in the same way as function declarations and can only be called after they have been defined. They can be named or anonymous.

`const multiply = function(a, b) {`

`return a * b;`

`};`

`console.log(multiply(4, 2));` // Output: 8

## Key differences between declaration and expression

**Expression:** An expression is any segment of code that evaluates to a single value, such as a number, a string, a boolean, or a function object itself.

**Declaration:** A declaration is a statement that performs an action, such as creating a variable, function, or class, but does not inherently produce a value in the same way an expression does.

By a table:-

| **Feature** | **Function Declaration** | **Function Expression** |
| --- | --- | --- |
| **Hoisting** | **Hoisted** (can be called before its definition in the code). | **Not hoisted** (must be defined before being called). |
| **Syntax** | A standalone statement starting with the `function` keyword, requiring a name. | Created as part of a larger expression, often assigned to a variable (using `var`, `let`, or `const`). |
| **Naming** | **Must** have a name. | Can be **anonymous** (no name) or named. |
| **Usage Context** | Used for general-purpose, reusable functions in the main code flow. | Flexible, often used for callbacks, immediately invoked function expressions (IIFEs), and conditional function definitions. |
| **Semicolon** | Does not require a semicolon at the end of the declaration. | Often followed by a semicolon because it is part of a larger statement (e.g., an assignment statement). |

Hoisting is a core JavaScript behavior where declarations of functions, variables, and classes are conceptually moved to the top of their containing scope during the compilation phase, before the code is executed.

**Key Points of Hoisting (Very High Level)**

**Declarations, Not Initializations:** Only the declaration is hoisted, not the assignment of a value.

**Different Behaviors:** Hoisting behavior differs depending on how the item is declared:

`var` **variables:** These are hoisted to the top of their scope (global or function) and initialized with `undefined`.

`let` **and** `const` **variables:** These are also hoisted, but they are *not* initialized. Attempting to access them before their declaration results in a `ReferenceError` because they are in a "Temporal Dead Zone" (TDZ).

**Function declarations:** The entire function (name and body) is fully hoisted, allowing you to call the function anywhere within its scope, even before its definition in the code.

**Function expressions/Arrow functions:** These behave like variables (using `var`, `let`, or `const`), so only the variable declaration is hoisted, not the function assignment itself. Calling them before the assignment will result in a `TypeError` or `ReferenceError`.

## When to use each type ?

When to use each type depends on how you want the function to behave. Function declarations are useful when the function is a main part of the program and you may want to call it before it appears in the code, because declarations are hoisted. They are commonly used for general reusable functions. Function expressions are useful when functions need to be created inside variables, passed as arguments, or used only in a specific place. They are often used in callbacks, event handlers, or when you want more control over when the function is created and used.
