Bayangin rumah kamu: di lobby, semua orang bisa ngakses (umum). Di kamar kamu, cuma kamu yang boleh masuk (privat). Di laci kamar, bahkan diri sendiri kadang harus pake kunci (super privat). Variabel di JavaScript juga punya "tingkat akses" yang dipanggil scope. Variabel global = lobby (siapapun bisa pakai). Variabel function = kamar (cuma kode di dalam fungsi yang bisa). Variabel block = laci (cuma kode di dalam {}).
💡 Plus bonus hoisting. JavaScript "ngangkat" deklarasi variabel ke atas scope sebelum kode jalan — fenomena unik yang gak ada di banyak bahasa lain.
vardi-hoist + diisiundefined.let/constdi-hoist tapi gak boleh diakses sampai baris deklarasi (Temporal Dead Zone). Sumber bug subtle yang nyiksa pemula.
- Global scope — bisa diakses di mana saja
- Function scope — hanya di dalam fungsi
- Block scope — hanya di dalam
{}(untukletdanconst)
let global = "bisa di mana saja";
function contoh() {
let lokal = "hanya di sini";
if (true) {
let blok = "hanya di if ini";
}
// blok tidak bisa diakses di sini
}
Hoisting — JavaScript "mengangkat" deklarasi ke atas sebelum kode dijalankan:
console.log(x); // undefined (bukan error!)
var x = 5;
console.log(y); // Error! (let tidak di-hoist seperti var)
let y = 10;
var di-hoist dan diberi nilai undefined. let dan const di-hoist tapi tidak bisa diakses sebelum dideklarasikan (Temporal Dead Zone).
🎭 Analogi sehari-hari
Scope = ruangan kantor. Global = lobby (semua orang akses). Function scope = kamar pribadi (cuma yang di dalam). Block scope = laci di kamar (cuma akses dari laci).
Hoisting = pengumuman dipasang lebih awal di papan, sebelum kontennya siap. var di-hoist + diisi undefined (papan ada, isi belum). let/const di-hoist tapi DI-LARANG akses sampai baris deklarasi (Temporal Dead Zone) — papan ditutup sampai siap.
⚠️ Jebakan yang sering ditemui:
varbocor ke fungsi —varpunya function scope, bukan block scope.if (true) { var x = 1 }bikinxbisa diakses di luarif. Selalu pakailet.for (var i = 0; ...)di setTimeout — semua callback bacaiyang sama (karenavarshared), output semua angka terakhir.let ifix-nya.- TDZ membingungkan —
typeof undeclaredVaraman, tapitypeof letVarInTDZerror. Pernah bikin runtime error di kode "defensive".- Function declarations fully hoisted —
function foo() {}bisa dipanggil sebelum baris deklarasi.const foo = () => {}tidak bisa (TDZ).- Closure di loop — function expression di dalam loop pakai variabel loop. Dengan
var, semua closure share variabel yang sama.letbikin scope baru per iterasi.Tips: Gunakan
letdanconstuntuk menghindari masalah hoisting. Hindarivardi kode modern.
TL;DR: Scope = level akses variabel. Global (semua bisa), Function (cuma di dalam fungsi), Block (cuma di {} — let/const). Hoisting = JavaScript "ngangkat" deklarasi ke atas scope sebelum kode jalan. var di-hoist + diisi undefined. let/const di-hoist tapi gak boleh diakses sampai baris deklarasi (TDZ — error). Function declaration fully hoisted (bisa dipanggil sebelum deklarasi), arrow function di const tidak. Modern JS: pakai let/const, hindari var.