# 🚀 JavaScript Hoisting: Konsep Fundamental yang Sering Disalahpahami Developer Pemula

Banyak developer pemula—bahkan yang sudah bekerja profesional—masih memiliki pemahaman yang kurang tepat tentang **hoisting** di JavaScript. Kamu mungkin pernah melihat variabel digunakan *sebelum* dideklarasikan dan bertanya-tanya: *“Kok bisa? Bukannya itu error?”*

Pada artikel ini, kita akan membahas konsep hoisting secara komprehensif, mulai dari definisi sederhana, contoh, perilaku `var`, `let`, dan `const`, hingga kaitannya dengan **Temporal Dead Zone (TDZ)**, serta bagaimana best practice yang seharusnya digunakan dalam production-level code.

## 🔍 Apa Itu Hoisting?

Hoisting adalah mekanisme javascript memindahkan deklarasi variable atau function ke atas scope sebelum eksekusi kode dijalankan. Secara teknis, yang di-**hoist** hanya deklarasi bukan assignment.

## 📌 Cara Kerja Hoisting pada JavaScript Engine

Sebelum kode kamu di eksekusi, javascript memilki dua fase:

1. Creation Phase (Memory allocation)
    
2. Execution Phase (Run code line by line)
    

Pada fase creation, semua function declaration, var, let dan const di catat dan di siapkan di memory - inilah proses yang di sebut hoisting.

Diagram singkat:

```javascript
📌 Creation Phase
- var → allocated (value = undefined)
- let → allocated (no value yet → enters TDZ)
- const → allocated (must have initialization)
- function declaration → fully hoisted with body
```

## 🧪 Contoh Dasar Hoisting

### ❓ Tanpa memahami hoisting

```javascript
console.log(name);
var name = "Alice";
```

Output:

```javascript
undefined
```

### ✔️ Penjelasan sebenarnya

```javascript
var name;          // hoisted
console.log(name); // undefined
name = "Alice";
```

## 🧩 Function Hoisting

Function declaration **di-hoist sempurna**, sehingga boleh dipanggil sebelum didefinisikan.

```javascript
greet();

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

Output:

```javascript
Hello World!
```

Namun **function expression** tidak di-hoist sebagai fungsi:

```javascript
sayHi(); // ❌ TypeError

var sayHi = function () {
  console.log("Hi!");
};
```

## 📙 Hoisting pada `var` vs `let` vs `const`

| Behavior | var | let | const |
| --- | --- | --- | --- |
| Hoisted | ✔️ | ✔️ | ✔️ |
| Default value during creation | `undefined` | No value | No value |
| Accessible before declaration | ✔️ | ❌ (TDZ) | ❌ (TDZ) |
| Must be initialized | ❌ | ❌ | ✔️ |

## 🔥 Mengenal **Temporal Dead Zone (TDZ)**

`let` dan `const` memang di-hoist, tetapi berada dalam **zona larangan akses** yang disebut **TDZ** sampai interpreter menemukan deklarasinya.

```javascript
console.log(age); // ❌ ReferenceError
let age = 20;
```

Ini terjadi karena pada saat akses, variabel sudah dideklarasikan **di memory**, tetapi **belum aktif**.

## 🎭 Analogi Hoisting yang Mudah Dipahami

Bayangkan kamu masuk kelas, dan guru sudah menyiapkan **daftar absensi kosong** (deklarasi). Kolom nama sudah tersedia, tetapi **belum ada isinya** (belum assignment).  
Saat kalian memperkenalkan diri, barulah kolom terisi.

* `var` → kolom sudah bisa dilihat, tapi **isi awal kosong (undefined)**
    
* `let` / `const` → kolom ada tapi **tidak boleh dibuka** sampai guru mulai absen
    

---

## 🧠 Kenapa Hoisting Ada?

Hoisting bukan bug, tapi **fitur desain JavaScript** yang:

* Mendukung *function-first* programming style
    
* Memungkinkan penggunaan function declaration di berbagai tempat
    
* Memudahkan interpreter membaca kode sebelum mengeksekusinya
    

---

## 🏁 Best Practice — Clean & Predictable Code

Untuk menghindari bug dan ambiguitas:

✔ Selalu deklarasikan variabel **di awal scope**  
✔ Gunakan `let` dan `const`, hindari `var`  
✔ Gunakan function declaration untuk utilities  
✔ Gunakan ESLint rule: `no-use-before-define`

Contoh kode yang disarankan:

```javascript
const name = "Alice";

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

greet();
```

---

## 📌 Kesimpulan Utama

* **Hoisting = deklarasi diangkat ke atas scope**
    
* `var`, `let`, `const`, dan function declaration semuanya di-hoist
    
* `var` di-hoist dengan nilai awal `undefined`
    
* `let` dan `const` berada dalam **Temporal Dead Zone**
    
* Function declaration bisa dipanggil sebelum deklarasi
    
* Function expression **tidak** ter-hoist sebagai fungsi
    

Hoisting bukan sesuatu yang harus dihindari, tapi **dipahami** agar tidak menulis kode yang penuh kejutan.

---

## 🎁 Bonus — Satu Kalimat yang Mudah Diingat

> "Hoisting mengangkat **deklarasi**, bukan **nilai**, dan **bukan izin untuk memakai variabel sebelum waktunya**."
