Scope adalah wilayah kode tempat sebuah variabel bisa dipakai. Variabel yang dibuat di luar semua fungsi bisa dibaca dari mana saja, sedangkan yang dibuat di dalam fungsi atau di dalam { } cuma berlaku di situ. Hoisting adalah kebiasaan JavaScript mencatat semua deklarasi lebih dulu, sebelum baris pertama dijalankan.
🧪 Tebakan cepat:
console.log(a)ditulis sebelumvar a = 5. Hasilnya error atau bukan? Tebak dulu, jawabannya ada di bagian "Hoisting: deklarasi dicatat duluan".
Global dan fungsi: dari dalam boleh, dari luar gak
let kota = "Bandung";
function cetakKota() {
let pesan = "Aku di ";
return pesan + kota;
}
console.log(cetakKota()); // Aku di Bandung
console.log(pesan); // ReferenceError: pesan is not defined
kotadibuat di luar semua fungsi, jadi dia variabel global: bisa dibaca dari mana saja, termasuk dari dalamcetakKota. Fungsinya gak perlu bikin salinan sendiri.pesandibuat di dalam fungsi, jadi cuma ada di dalam fungsi itu (function scope).- Dari luar,
pesangak dikenal. Membacanya melemparReferenceError, error yang artinya "nama ini gak ada di sini".
Aturannya satu arah: kode di dalam bisa melihat variabel di luarnya, tapi kode di luar gak bisa melihat ke dalam.
Block: let dan const berhenti di { }
let x = 1;
{
let x = 2;
console.log(x); // 2
}
console.log(x); // 1
- Sepasang
{ }membentuk block, misalnya badanifataufor, atau{ }sendirian kayak di atas. letdanconstcuma hidup di dalam block tempat mereka dibuat (block scope).xdi dalam block adalah variabel lain, terpisah darixdi luar.- Jadi yang tercetak
2, lalu1.
var gak peduli block, dia cuma berhenti di batas fungsi. { var y = 1; } lalu console.log(y) tetap mencetak 1, karena y bocor keluar block. Ini salah satu alasan var dihindari.
Hoisting: deklarasi dicatat duluan
console.log(a); // undefined
var a = 5;
sapa(); // Halo!
function sapa() {
console.log("Halo!");
}
console.log(b); // ReferenceError
let b = 10;
var adicatat lebih dulu dan langsung diisiundefined. Angka 5 baru masuk waktu barisnya jalan. Jawaban tebakan: bukan error, hasilnyaundefined.- Function declaration dicatat lengkap dengan isinya, jadi
sapa()bisa dipanggil sebelum barisnya. Fungsi yang disimpan di variabel, kayakconst sapa = function () {...}, gak ikut. let b(danconst) juga dicatat, tapi belum boleh dipakai sampai barisnya jalan. Wilayah sebelum barisnya disebut Temporal Dead Zone (TDZ), dan membacanya melemparReferenceError.
Closure: fungsi yang ingat variabelnya
Fungsi juga sebuah nilai, jadi fungsi bisa mengembalikan fungsi lain. Fungsi dalam itu tetap ingat variabel di scope tempat ia dibuat:
function buatTabungan() {
let saldo = 0;
return function () {
saldo = saldo + 1000;
return saldo;
};
}
const nabung = buatTabungan();
console.log(nabung()); // 1000
console.log(nabung()); // 2000
buatTabunganbikinsaldo, lalu mengembalikan sebuah fungsi.const nabung = buatTabungan();menyimpan fungsi itu.- Fungsi dalam bisa membaca dan mengubah
saldo, walaubuatTabungansudah selesai jalan. Ini disebut closure. saldodibuat sekali saja, waktubuatTabungan()dipanggil, jadi tiapnabung()melanjutkan hitungan sebelumnya.- Nilainya dinaikkan dulu, baru dikembalikan, jadi panggilan pertama memberi 1000. Buat menaikkan 1, tulis
hitung++, singkatan darihitung = hitung + 1, di barisnya sendiri sebelumreturn hitung;.
⚠️ Jebakan yang sering ketemu
- Penghitung dibuat di dalam fungsi dalam. Kalau
let saldo = 0pindah ke dalam fungsi yang dikembalikan, ia dibuat ulang tiap panggilan, jadi hasilnya selalu 1000. return hitung++. Bentuk ini mengembalikan nilai sebelum naik. Naikkan dulu, barureturn hitung.- Bikin variabel baru dengan nama yang sama di dalam fungsi.
let kota = ...di dalamcetakKotamenutupikotayang global. Kalau mau membaca yang global, cukup pakai namanya.
TL;DR: Scope menentukan di mana variabel bisa dipakai. Global bisa dibaca dari mana saja, variabel fungsi cuma di dalam fungsinya, dan let atau const cuma di dalam { }-nya. var bocor keluar block. Hoisting mencatat deklarasi lebih dulu: var bernilai undefined sebelum barisnya, let dan const melempar ReferenceError (TDZ), function declaration bisa dipanggil sebelum barisnya. Fungsi yang dikembalikan fungsi lain tetap ingat variabel luarnya (closure).