# Hoisting in JavaScript

# Hoisting

JavaScript behaves differently from many other programming languages.  
One of its unique behaviors is called **hoisting**.

Hoisting affects how variables and functions are created.  
It can confuse beginners, and even experienced developers sometimes forget how it works.

In this article, you will learn:

* what hoisting means
    
* how variable hoisting works
    
* how function hoisting works
    
* common mistakes
    
* the “correct mental model” to avoid bugs
    

Let’s start with the definition.

---

## What Is Hoisting?

**Hoisting means JavaScript moves variable and function declarations to the top of their scope before code runs.**

This does *not* mean your code is rearranged.  
It means JavaScript creates memory for these declarations during the “creation phase” of execution.

So you can use some variables and functions even before they appear in your code.

---

# Function Hoisting

Function declarations are fully hoisted.

This means you can call the function **before** you write it.

Example:

```javascript
sayHello(); // Output: Hello!

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

This works because during hoisting, JavaScript stores the entire function in memory.

### When is this useful?

* It allows you to write code in any order.
    
* You can place helper functions at bottom and main logic at the top.
    

---

# Variable Hoisting

Variables behave differently depending on whether you use:

* `var`
    
* `let`
    
* `const`
    

Let’s look at each one.

---

## 1\. Hoisting with `var`

Variables declared with `var` are hoisted but initialized with `undefined`.

Example:

```javascript
console.log(a); // undefined
var a = 10;
```

The variable exists at the top of the scope, but it does not have a value yet.

---

## 2\. Hoisting with `let` and `const`

`let` and `const` are also hoisted, but they are **not initialized**.

They are placed in something called the **Temporal Dead Zone (TDZ)** until the line where they are declared.

Example:

```javascript
console.log(x); //  ReferenceError
let x = 5;
```

Why the error?

Because `x` exists, but JavaScript does not allow you to use it before declaration.

Same with `const`:

```javascript
console.log(y); //  ReferenceError
const y = 20;
```

### The Temporal Dead Zone (TDZ)

The TDZ is the region from the start of the scope to the line where the variable is declared.

You cannot access the variable in this zone.

---

# Correct Mental Model for Hoisting

Think of hoisting like this:

### During the Memory Creation Phase:

* Function declarations → stored as full functions
    
* `var` → stored as `undefined`
    
* `let` and `const` → allocated but not initialized (TDZ)
    

### During the Execution Phase:

* Code runs line by line
    
* Values are assigned
    
* TDZ ends at the declaration line
    

---

# Function Declaration vs Function Expression

Hoisting behaves differently depending on the syntax.

---

## 1\. Function Declarations (fully hoisted)

```javascript
greet(); // Works!

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

---

## 2\. Function Expressions (NOT fully hoisted)

Using `var`:

```javascript
greet(); // TypeError: greet is not a function

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

Why?

`var greet` becomes `undefined` during hoisting.  
So at the time of the call, `greet` is undefined, not a function.

---

## 3\. Arrow Functions

Arrow functions behave like function expressions.

Using `let`:

```javascript
greet(); // ReferenceError

let greet = () => {
  console.log("Hello!");
};
```

They stay in the Temporal Dead Zone until declared.

---

# Common Mistakes with Hoisting

### Mistake 1: Using variables before declaring them

```javascript
console.log(score); // ReferenceError
let score = 100;
```

### Mistake 2: Assuming `var` is safe because it does not throw error

```javascript
console.log(a); // undefined, not error
var a = 1;
```

This often causes silent bugs.

### Mistake 3: Assuming all functions are hoisted the same way

```javascript
run(); //  Error

let run = function () {};
```

Function expressions are not hoisted like declarations.

---

# Best Practices to Avoid Hoisting Bugs

✔ Always declare variables at the top of the scope  
✔ Use `let` and `const` instead of `var`  
✔ Write functions before calling them (even though not required)  
✔ Avoid mixing declarations and usage in confusing order  
✔ Use `const` for functions when possible

These practices make your code predictable and easier to read.

---

# Summary

| Item | Hoisted? | Initialized? | Usable before declaration? |
| --- | --- | --- | --- |
| `var` | Yes | `undefined` | Yes (but unsafe) |
| `let` | Yes | No (TDZ) | No |
| `const` | Yes | No (TDZ) | No |
| Function Declaration | Yes | Yes (full function) | Yes |
| Function Expression | Yes (variable only) | No | No |
| Arrow Function | Yes (variable only) | No | NoHoisting in JavaScript: A Simple Guide for Beginners |
