Struktur Program

BAB 6: Variabel dan Binding

Menyimpan nilai dengan let, const, dan var -- cara kerja binding dan aturan penamaan.

Di bab-bab sebelumnya, ekspresi seperti 3 + 4 atau "halo" baru bermakna ketika langsung dievaluasi. Tapi bagaimana kalau kita ingin mengingat sebuah nilai dan memakainya lagi di baris berikutnya? Di situlah variabel masuk — sebagai cara JavaScript untuk "mengingat" sesuatu.

Dalam dunia JavaScript, istilah yang lebih tepat sebenarnya adalah binding: kita mengikat sebuah nama ke sebuah nilai. Nama itulah yang kemudian kita gunakan untuk merujuk ke nilai tersebut kapanpun kita butuhkan.

Mendeklarasikan Binding

Ada tiga kata kunci untuk membuat binding di JavaScript: let, const, dan var. Ketiganya punya perilaku yang berbeda, dan perbedaan itu penting untuk dipahami — bukan sekadar dihafal.

Mulai dari yang paling umum dipakai saat ini:

JavaScriptJAVASCRIPT
// catatan-belajar.js
let namaMataKuliah = "Kalkulus";
let nilaiUjian = 85;

console.log(namaMataKuliah); // "Kalkulus"
console.log(nilaiUjian);    // 85

Kata kunci let memberi tahu JavaScript: "Tolong buat tempat penyimpanan baru dan ikat nama ini ke nilai itu." Setelah itu, kapanpun kamu menulis nilaiUjian, JavaScript tahu harus mencari ke tempat penyimpanan yang sudah dibuat tadi.

Yang menarik: binding bisa diubah. Nilai yang disimpan bukan ukiran di batu.

JavaScriptJAVASCRIPT
// catatan-belajar.js
let nilaiUjian = 85;
console.log(nilaiUjian); // 85

nilaiUjian = 92;
console.log(nilaiUjian); // 92

Perhatikan baris ketiga — tidak ada let lagi. Menulis let nilaiUjian untuk kedua kalinya di scope yang sama justru akan menyebabkan error. let hanya digunakan saat pertama kali mendeklarasikan binding.

Konstanta dengan const

Kadang kita punya nilai yang tidak boleh berubah — nama program, nilai pi, konfigurasi yang sudah fixed. Untuk kasus ini, const adalah pilihan yang tepat.

JavaScriptJAVASCRIPT
// catatan-belajar.js
const NAMA_APLIKASI = "TrackBelajar";
const VERSI = "1.0.0";

console.log(NAMA_APLIKASI); // "TrackBelajar"

Mencoba mengubah nilai const akan langsung menghasilkan error:

JavaScriptJAVASCRIPT
const NAMA_APLIKASI = "TrackBelajar";
NAMA_APLIKASI = "StudyTrack"; // TypeError: Assignment to constant variable.

Konvensi umum yang sering ditemukan: nama konstanta yang benar-benar tidak berubah sepanjang program (biasanya nilai konfigurasi) ditulis dengan HURUF_BESAR_DAN_UNDERSCORE. Tapi ini hanya konvensi, bukan aturan JavaScript.

Biasakan menggunakan const sebagai default. Ganti ke let hanya ketika kamu memang perlu mengubah nilainya di kemudian hari. Ini membuat kode lebih mudah dibaca — pembaca langsung tahu bahwa binding ini tidak akan berubah.

const Bukan Berarti Immutable Sepenuhnya

Ada hal yang sering membingungkan pemula: const hanya mengunci binding-nya, bukan isi datanya. Kalau yang disimpan adalah object atau array, isinya masih bisa diubah.

JavaScriptJAVASCRIPT
const daftarMataKuliah = ["Kalkulus", "Fisika", "Kimia"];
daftarMataKuliah.push("Biologi"); // ini valid

console.log(daftarMataKuliah);
// ["Kalkulus", "Fisika", "Kimia", "Biologi"]

daftarMataKuliah = ["Sastra"]; // TypeError: ini tidak valid

Yang dikunci oleh const adalah "daftarMataKuliah tidak boleh menunjuk ke array yang berbeda" — bukan "array yang ditunjuk tidak boleh dimodifikasi."

Warisan: Keyword var

Sebelum ES6 (2015), satu-satunya cara mendeklarasikan variabel di JavaScript adalah dengan var. Kamu akan sering menemuinya di kode-kode lama, jadi penting untuk tahu cara kerjanya — meski untuk kode baru kita tidak lagi menggunakannya.

JavaScriptJAVASCRIPT
var skorTertinggi = 100;
console.log(skorTertinggi); // 100

Masalah dengan var ada dua:

Pertama, var tidak mengenal block scope. Artinya, variabel yang dideklarasikan di dalam sebuah blok {} tetap bisa diakses dari luar blok itu.

JavaScriptJAVASCRIPT
if (true) {
  var pesanSementara = "ini dari dalam blok";
}
console.log(pesanSementara); // "ini dari dalam blok" -- bocor keluar!

Bandingkan dengan let:

JavaScriptJAVASCRIPT
if (true) {
  let pesanSementara = "ini dari dalam blok";
}
console.log(pesanSementara); // ReferenceError: pesanSementara is not defined

Kedua, var mengalami hoisting dengan cara yang tidak intuitif. JavaScript "mengangkat" deklarasi var ke puncak scope-nya, tapi tidak nilai awalnya.

JavaScriptJAVASCRIPT
console.log(nilaiAwal); // undefined, bukan error
var nilaiAwal = 42;

Ini perilaku yang membingungkan — variabel "ada" sebelum dideklarasikan, tapi nilainya undefined. Dengan let, JavaScript langsung melempar error jika kamu mencoba mengakses binding sebelum deklarasinya.

Jangan gunakan var di kode baru. Perilakunya yang tidak konsisten sudah menjadi sumber bug selama bertahun-tahun. Gunakan let atau const sepenuhnya.

Aturan Penamaan Binding

Nama yang kamu berikan ke binding disebut identifier. JavaScript punya beberapa aturan yang harus diikuti:

Aturan yang wajib dipatuhi (kalau dilanggar, JavaScript akan error):

  • Harus dimulai dengan huruf, underscore _, atau tanda dollar $
  • Boleh mengandung angka, tapi tidak di awal
  • Tidak boleh menggunakan reserved words seperti let, if, return, class, dan sejenisnya

Contoh nama yang valid dan tidak valid:

JavaScriptJAVASCRIPT
let nilaiAkhir = 90;    // valid
let _catatan = "ok";   // valid
let $harga = 15000;    // valid
let nilai2024 = 95;    // valid

let 2024nilai = 95;    // SyntaxError: dimulai dengan angka
let nilai-akhir = 90;  // SyntaxError: tanda minus tidak diizinkan
let let = "apa";       // SyntaxError: reserved word

Untuk style, JavaScript community umumnya menggunakan camelCase untuk nama variabel biasa: nilaiAkhir, daftarMataKuliah, skorTertinggi. Ini bukan aturan bahasa, tapi konvensi yang sangat luas diikuti.

Block Scope dan Temporal Dead Zone

let dan const mengikuti block scope — sebuah binding hanya hidup di dalam blok {} tempat ia dideklarasikan.

JavaScriptJAVASCRIPT
// catatan-belajar.js
let semester = "Ganjil";

{
  let nilaiIP = 3.75;
  console.log(semester);  // "Ganjil" -- bisa diakses, dideklarasikan di luar
  console.log(nilaiIP);   // 3.75
}

console.log(semester);  // "Ganjil" -- masih bisa diakses
console.log(nilaiIP);   // ReferenceError: nilaiIP is not defined

Ada satu perilaku let dan const yang perlu dipahami: temporal dead zone (TDZ). Meskipun JavaScript "tahu" tentang keberadaan binding yang dideklarasikan dengan let sejak awal blok, binding itu tidak bisa digunakan sebelum baris deklarasinya.

JavaScriptJAVASCRIPT
console.log(statusMahasiswa); // ReferenceError: Cannot access before initialization
let statusMahasiswa = "Aktif";

Ini berbeda dari var yang akan mengembalikan undefined di situasi yang sama. TDZ dirancang untuk membantu kita mendeteksi bug lebih awal — jika kamu mengakses variabel sebelum mendeklarasikannya, itu hampir selalu kesalahan.

Binding Tanpa Nilai Awal

let memperbolehkan deklarasi tanpa nilai awal. Dalam kondisi itu, nilai binding adalah undefined sampai kamu mengisinya.

JavaScriptJAVASCRIPT
let statusKelulusan;
console.log(statusKelulusan); // undefined

statusKelulusan = "Lulus";
console.log(statusKelulusan); // "Lulus"

const tidak memperbolehkan ini — karena kamu tidak bisa mengubahnya setelah dideklarasikan, mendeklarasikan const tanpa nilai awal tidak ada gunanya dan JavaScript akan langsung error.

JavaScriptJAVASCRIPT
const KODE_PRODI; // SyntaxError: Missing initializer in const declaration

Latihan

Tiga soal berikut mengajak kamu membangun kebiasaan memilih let vs const dengan tepat, sekaligus melatih intuisi tentang scope.

  1. Deklarasikan sebuah variabel untuk menyimpan nilai ujian seorang mahasiswa, lalu ubah nilainya setelah pengumuman remedial. Gunakan keyword yang paling tepat. Mengapa bukan yang lainnya?

  2. Buat sebuah program kecil yang mendeklarasikan const BATAS_SKS = 24 di luar blok, kemudian di dalam sebuah blok {} buat let sksDiambil = 20. Cetak keduanya dari dalam blok, lalu coba cetak sksDiambil dari luar blok — apa yang terjadi dan mengapa?

  3. Jalankan kode berikut dan perhatikan hasilnya. Lalu ganti var dengan let dan jalankan lagi. Jelaskan perbedaan perilakunya:

    JavaScriptJAVASCRIPT
    console.log(targetNilai);
    var targetNilai = 80;
    

Sejauh ini kamu sudah tahu cara menyimpan nilai di JavaScript — mengisi binding dengan angka, teks, atau apapun. Tapi program yang hanya menyimpan dan mencetak nilai tidak terlalu berguna. Dalam kehidupan nyata, kita perlu program yang bisa memutuskan: jika nilai ujian di bawah 60, cetak "Tidak lulus"; jika tidak, cetak "Lulus". Kemampuan membuat keputusan seperti inilah yang akan kita pelajari selanjutnya.

Referensi

  1. 1 let - JavaScript | MDN Web Docs
  2. 2 const - JavaScript | MDN Web Docs
  3. 3 Grammar and types - JavaScript Guide | MDN Web Docs
  4. 4 var - JavaScript | MDN Web Docs