JavaScript menyediakan tiga kata kunci untuk membuat variabel: let, const, dan var. Ketiganya membuat wadah bernama, tetapi aturan mainnya berbeda pada titik-titik yang penting: di mana wadah terlihat, apakah isinya boleh ditimpa, dan apa yang terjadi saat kode dibaca sebelum wadah terisi. Memilih kata kunci yang keliru tidak selalu berujung pesan error — sering kali berujung bug yang baru terlihat di bagian program lain. Karena itu perbedaannya perlu dibuktikan, bukan sekadar dihafal.

Chapter ini menjalankan satu berkas contoh di Node yang memperlihatkan perilaku ketiganya sekaligus, merangkum hasilnya dalam tabel perbandingan, lalu menutup dengan panduan memilih. Sepanjang demonstrasi kita menggunakan blok try-catch semata-mata agar program tetap berjalan meskipun ada error yang disengaja; pembahasan penuhnya menunggu di section Error Handling.

Mengamati Perilaku Ketiganya #

Berkas berikut berisi empat eksperimen berurutan: membaca var sebelum deklarasinya, membaca let sebelum deklarasinya, menimpa nilai const, dan membandingkan batasan blok:

js deklarasi.js
// deklarasi.js
// Membuktikan perilaku let, const, dan var langsung di Node.

// --- var: terangkat (hoisting), terbaca sebelum dideklarasikan ---
console.log("var sebelum deklarasi:", jumlahStok);
var jumlahStok = 25;
console.log("var setelah deklarasi:", jumlahStok);

// --- let: tidak dapat diakses sebelum baris deklarasinya dieksekusi ---
try {
  console.log("let sebelum deklarasi:", namaKota);
  let namaKota = "Bandung";
  console.log("let setelah deklarasi:", namaKota); // tidak sempat berjalan
} catch (error) {
  console.log(error.name, "-", error.message);
}

// --- const: nilai ikatannya tidak dapat ditimpa ---
const pajak = 0.11;
try {
  pajak = 0.12;
} catch (error) {
  console.log(error.name, "-", error.message);
}

// --- let dan const terkurung di dalam blok; var tidak ---
{
  var kodeCabang = "JKT-02";
  let kotaCabang = "Jakarta";
}

console.log("var keluar dari blok:", kodeCabang);

try {
  console.log("let di luar blok:", kotaCabang);
} catch (error) {
  console.log(error.name, "-", error.message);
}

Output yang Dihasilkan:

text
var sebelum deklarasi: undefined
var setelah deklarasi: 25
ReferenceError - Cannot access 'namaKota' before initialization
TypeError - Assignment to constant variable.
var keluar dari blok: JKT-02
ReferenceError - kotaCabang is not defined

Mari kita telaah apa yang terjadi pada baris-baris kode di atas:

  1. Baris 5 (console.log("var sebelum deklarasi:", jumlahStok);): variabel jumlahStok belum dideklarasikan di baris ini, tetapi tidak muncul error. Deklarasi var diangkat (hoisting) saat program dimuat, sehingga wadahnya sudah ada — isinya baru undefined.
  2. Baris 6–7 (var jumlahStok = 25; dst.): assignment mengisi wadah hasil hoisting, dan pembacaan berikutnya menampilkan 25.
  3. Baris 11–12 (console.log("let sebelum deklarasi:", namaKota); lalu let namaKota = "Bandung";): let juga diangkat, tetapi tanpa nilai awal — wadahnya berada di zona yang belum boleh diakses (temporal dead zone) sampai baris deklarasinya dieksekusi. Pembacaan memunculkan ReferenceError: Cannot access 'namaKota' before initialization, dan eksekusi lompat ke blok catch.
  4. Baris 19–21 (const pajak = 0.11; lalu pajak = 0.12;): const mengunci ikatan nama ke nilainya. Percobaan menimpa pajak memunculkan TypeError: Assignment to constant variable. — error yang jelas, bukan perilaku diam-diam.
  5. Baris 27–30 ({ var kodeCabang ...; let kotaCabang ...; }): pasangan kurung kurawal membentuk blok. let dan const terkurung di dalamnya, sedangkan var mengabaikan batas blok dan menempel ke scope di luar.
  6. Baris 32 (console.log("var keluar dari blok:", kodeCabang);): JKT-02 tampil karena kodeCabang milik var lolos dari blok.
  7. Baris 34–35 (console.log("let di luar blok:", kotaCabang);): kotaCabang tidak dikenal di luar blok, sehingga memunculkan ReferenceError: kotaCabang is not defined. Perilaku ini justru diharapkan: batas variabel menjadi tegas.

Perhatikan bahwa setiap error di atas tertangkap catch sehingga program berjalan sampai baris terakhir. Tanpa try-catch, error pertama akan menghentikan program di tengah jalan.

Tabel Perbandingan #

Hasil keempat eksperimen tadi bisa dirangkum ke dalam satu tabel:

Aspekletconstvar
Scopeblock scopeblock scopefunction scope / global
Menimpa nilai (reassignment)bolehtidak — TypeErrorboleh
Deklarasi ulang di scope yang samaSyntaxErrorSyntaxErrorboleh
Akses sebelum baris deklarasi dieksekusiReferenceError (temporal dead zone)ReferenceError (temporal dead zone)undefined (hoisting)
Wajib diisi saat deklarasitidakwajib — tanpa isi: SyntaxErrortidak
Cakupan blok {}terkurungterkurunglolos keluar blok

Dua catatan tentang const sebelum kita lanjut. Pertama, const mengunci ikatan nama ke nilai — bukan mengunci isi nilai itu sendiri; penjelasan lengkapnya menunggu kita mengenal object di section Objects. Kedua, dua baris galat berikutnya bersifat berbeda dari error pada berkas contoh: keduanya SyntaxError, yang muncul saat program dimuat, jauh sebelum baris mana pun dieksekusi — sehingga tidak bisa ditangkap try-catch.

Kesalahan yang Terjadi Saat Parsing #

Mendeklarasikan let dua kali dalam scope yang sama ditolak langsung oleh engine. Jika berkas berikut dijalankan:

js
let totalNilai = 10;
let totalNilai = 20; // deklarasi ulang di scope yang sama

Node berhenti dengan pesan:

text
SyntaxError: Identifier 'totalNilai' has already been declared

Aturan serupa berlaku untuk const yang dideklarasikan tanpa nilai:

js
const tanpaIsi; // const wajib diisi saat deklarasi

Jika dijalankan:

text
SyntaxError: Missing initializer in const declaration

Kedua pesan di atas muncul sebelum satu statement pun berjalan — engine menolak berkas yang strukturnya tidak sah. Inilah keuntungan aturan yang ketat: kesalahan terdeteksi lebih awal, bukan saat program sudah setengah berjalan.

Kapan Memakai yang Mana #

Panduan yang lazim di industri JavaScript:

  • Default-kan const: pakai untuk setiap variabel yang nilainya tidak akan ditimpa. Jika suatu saat perlu berubah, turunkan ke let.
  • Pakai let untuk nilai yang memang akan diperbarui, seperti penghitung dan saldo.
  • Hindari var di kode baru. var masih dijumpai di kode lama (legacy), jadi aturan mainnya tetap perlu dipahami untuk membaca kode tersebut.

Dengan tiga kata kunci ini, wadah nilai kita sudah punya aturan yang jelas. Chapter berikutnya merapikan sisi yang belum dibahas: bagaimana sebaiknya kita menamai wadah tersebut.

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

deklarasi.js

Unduh berkas
javascript
// deklarasi.js
// Membuktikan perilaku let, const, dan var langsung di Node.

// --- var: terangkat (hoisting), terbaca sebelum dideklarasikan ---
console.log("var sebelum deklarasi:", jumlahStok);
var jumlahStok = 25;
console.log("var setelah deklarasi:", jumlahStok);

// --- let: tidak dapat diakses sebelum baris deklarasinya dieksekusi ---
try {
  console.log("let sebelum deklarasi:", namaKota);
  let namaKota = "Bandung";
  console.log("let setelah deklarasi:", namaKota); // tidak sempat berjalan
} catch (error) {
  console.log(error.name, "-", error.message);
}

// --- const: nilai ikatannya tidak dapat ditimpa ---
const pajak = 0.11;
try {
  pajak = 0.12;
} catch (error) {
  console.log(error.name, "-", error.message);
}

// --- let dan const terkurung di dalam blok; var tidak ---
{
  var kodeCabang = "JKT-02";
  let kotaCabang = "Jakarta";
}

console.log("var keluar dari blok:", kodeCabang);

try {
  console.log("let di luar blok:", kotaCabang);
} catch (error) {
  console.log(error.name, "-", error.message);
}