Percabangan memilih jalur eksekusi berdasarkan kondisi yang diperiksa saat program berjalan. Topik ini membahas rantai if, else if, dan else untuk keputusan bertingkat, aturan truthiness yang menentukan kapan sebuah nilai dianggap benar, serta switch untuk membandingkan satu ekspresi dengan banyak nilai tetap. Semua contoh dijalankan dengan Node.js, sehingga keluarannya dapat diulang persis di terminal.
if, else if, dan else#
Pernyataan if mengeksekusi sebuah blok hanya bila kondisinya bernilai benar. Kondisi ditulis di dalam tanda kurung, sedangkan blok perintahnya ditulis di dalam kurung kurawal. Bila kondisi tidak terpenuhi, blok itu dilewati dan program berlanjut ke perintah berikutnya. Bentuk else menampung jalur ketika seluruh kondisi di atasnya gagal, sedangkan else if menyisipkan pemeriksaan tambahan di antara if dan else.
Saat rantai if dijalankan, kondisi diperiksa satu per satu dari atas ke bawah, dan pemeriksaan berhenti pada kondisi pertama yang benar. Setelah cabang yang cocok menjalankan badannya, seluruh cabang di bawahnya tidak diperiksa lagi. Alur itu terlihat pada diagram berikut, yang memetakan nilai ujian 86 ke predikatnya.
Rantai yang sama dituliskan sebagai berkas utuh di bawah ini. Berkasnya sengaja memuat dua versi, yaitu rantai yang benar dan rantai yang keliru urutan kondisinya, agar perbedaan hasilnya terlihat langsung. Jalankan berkasnya dengan node predikat-nilai.js untuk mengulang keluarannya.
// Urutan kondisi menentukan hasil: rantai yang benar dan yang keliru
const nilai = 86;
// rantai yang benar: kondisi paling ketat ditempatkan di atas
if (nilai >= 90) {
console.log("benar -> Predikat A");
} else if (nilai >= 80) {
console.log("benar -> Predikat B");
} else if (nilai >= 70) {
console.log("benar -> Predikat C");
} else {
console.log("benar -> Belum lulus");
}
// rantai yang keliru: kondisi longgar ditempatkan lebih dulu
if (nilai >= 70) {
console.log("keliru -> Predikat C");
} else if (nilai >= 80) {
console.log("keliru -> Predikat B"); // tidak pernah tercapai
} else if (nilai >= 90) {
console.log("keliru -> Predikat A"); // tidak pernah tercapai
} else {
console.log("keliru -> Belum lulus");
}benar -> Predikat B
keliru -> Predikat CPada keluaran, nilai 86 mendarat di Predikat B pada rantai pertama karena pemeriksaan >= 90 gagal sebelum >= 80 benar. Rantai kedua langsung menjawab Predikat C karena kondisi >= 70 diperiksa lebih dulu dan memang benar. Dua cabang di bawahnya tidak pernah sempat dievaluasi, sehingga urutan penulisan kondisi adalah bagian dari logika program, bukan sekadar gaya. Aturan praktisnya, letakkan kondisi paling ketat di atas, lalu longgarkan ke bawah.
Truthiness dalam praktik#
JavaScript tidak menuntut kondisi berupa perbandingan yang eksplisit. Nilai yang diuji if mengalami penilaian truthiness, yakni kecenderungan sebuah nilai diperlakukan sebagai benar atau salah. Nilai yang dianggap benar disebut truthy, sedangkan yang dianggap salah disebut falsy. Daftar nilai falsy pada JavaScript pendek dan tetap, sedangkan sisanya, termasuk array kosong dan string berisi karakter apa pun, selalu dianggap truthy.
| Nilai | Penilaian if |
|---|---|
false, 0, -0, 0n | falsy |
"" (string kosong) | falsy |
null, undefined, NaN | falsy |
[], {}, "0", "false" | truthy |
Tiga nilai pada tabel itu diuji langsung oleh potongan berikut. Kasus string perlu perhatian khusus karena string kosong dan string berisi nol sering dikira sama. Angka nol disertakan sebagai pembanding karena nilainya sah tetapi dianggap salah.
const nol = 0;
if (nol) {
console.log("0 -> dianggap benar");
} else {
console.log("0 -> dianggap salah");
}
const kosong = "";
if (kosong) {
console.log("\"\" -> dianggap benar");
} else {
console.log("\"\" -> dianggap salah");
}
const teksNol = "0";
if (teksNol) {
console.log("\"0\" -> dianggap benar");
} else {
console.log("\"0\" -> dianggap salah");
}0 -> dianggap salah
"" -> dianggap salah
"0" -> dianggap benarString kosong dianggap falsy karena tidak memuat karakter apa pun, sedangkan "0" adalah string berisi satu karakter sehingga dianggap truthy. Perbedaan ini penting saat membaca masukan, karena angka yang datang sebagai teks tidak berperilaku sama dengan angka sungguhan. Cara paling aman menghadapi nilai yang mungkin kosong adalah membandingkannya secara eksplisit, seperti pengecekan kolom nama berikut.
const nama = "";
if (nama === "") {
console.log("Nama belum diisi");
}
console.log("Lanjut memproses data");Nama belum diisi
Lanjut memproses dataNilai null dan undefined menandai ketiadaan data dan keduanya masuk daftar falsy. Masalah muncul ketika 0 dan string kosong justru merupakan nilai yang sah, misalnya catatan tanpa panggilan sama sekali. Bila ketiga keadaan itu perlu dibedakan, uji null dan undefined secara eksplisit seperti pada contoh berikut.
const namaPanggilan = null;
if (namaPanggilan === null || namaPanggilan === undefined) {
console.log("(belum diisi)");
} else {
console.log(namaPanggilan);
}(belum diisi)Pola yang sama disediakan JavaScript dalam satu baris lewat operator ?? (nullish coalescing). Operator ini mengambil nilai kiri bila kiri bukan null dan bukan undefined, dan beralih ke nilai kanan bila kiri kosong. Namanya merujuk pada pasangan null dan undefined, satu-satunya keadaan yang membuatnya bergeser.
const diminta = undefined;
// ?? mengambil nilai kiri bila kiri bukan null/undefined, sisanya pakai nilai kanan
const jumlahPerHalaman = diminta ?? 10;
console.log(jumlahPerHalaman);
const dimintaKedua = 24;
console.log(dimintaKedua ?? 10);10
24Demo berikut memungkinkan pencobaan truthiness langsung. Pilih salah satu nilai pada daftar, lalu perhatikan cabang yang dijalankan if beserta tipe datanya. Nilai array kosong sengaja disertakan karena sering dikira falsy padahal termasuk truthy.
switch dengan case, break, dan default#
Pernyataan switch membandingkan satu ekspresi dengan sejumlah nilai tetap, satu nilai per case. Ketika sebuah case cocok, eksekusi berpindah ke badannya dan berjalan sampai bertemu break. Kata default menampung semua nilai yang tidak cocok dengan case mana pun, sehingga perannya mirip else pada rantai if.
const hari = "Rabu";
let keterangan;
switch (hari) {
case "Sabtu":
case "Minggu":
keterangan = "akhir pekan";
break;
case "Senin":
keterangan = "awal pekan";
break;
default:
keterangan = "hari kerja";
}
console.log(`${hari} termasuk ${keterangan}`);Rabu termasuk hari kerjaPenggabungan case "Sabtu" dan case "Minggu" pada contoh di atas adalah satu badan yang dipakai bersama, pola yang dibahas lebih rinci di bawah. Rabu tidak terdaftar pada case mana pun, sehingga jalurnya jatuh ke default. Perbandingannya memakai ===, sehingga string "2" tidak akan cocok dengan angka 2.
Fallthrough yang disengaja dan yang keliru#
Fallthrough adalah perilaku switch yang melanjutkan eksekusi ke case berikutnya ketika break tidak ditulis. Perilaku ini bisa dimanfaatkan, misalnya menggabungkan beberapa case dengan badan kosong agar semuanya berbagi satu keluaran, seperti pasangan Sabtu dan Minggu pada bagian sebelumnya. Tanpa niat yang jelas, fallthrough justru menjadi sumber kekeliruan yang paling sulit dilihat. Contoh berikut memperagakan akibatnya pada penentuan bobot predikat.
const predikat = "B";
let bobot;
switch (predikat) {
case "A":
bobot = 4;
case "B":
bobot = 3;
case "C":
bobot = 2;
break;
default:
bobot = 0;
}
console.log(`Bobot ${predikat}: ${bobot}`);Bobot B: 2Predikat B seharusnya berbobot 3, tetapi keluarannya 2. Setelah case "B" mengisi bobot 3, eksekusi melanjutkan ke case "C" yang menimpanya menjadi 2, dan barulah break menghentikan switch. Tidak ada pesan error yang muncul, hasilnya hanya salah tanpa suara. Karena itu banyak tim mewajibkan break di setiap case, dan penggabungan case hanya dilakukan lewat badan kosong yang memang disengaja.
Kapan switch lebih jelas daripada else if#
switch paling unggul ketika satu ekspresi dibandingkan dengan sekumpulan nilai tetap, misalnya kode menu atau hari dalam seminggu. Setiap case terbaca sebagai satu kasus yang setara. Susunan seperti itu sulit dilihat pada rantai else if yang panjang. Sebaliknya, kondisi berupa rentang seperti nilai >= 80 tidak bisa ditulis sebagai case tanpa trik, sehingga rantai if tetap menjadi pilihan yang wajar. Kondisi yang menggabungkan beberapa variabel sekaligus juga hanya mungkin ditulis dengan if.
| Situasi | Pilihan yang cocok |
|---|---|
| Satu variabel dibandingkan dengan banyak nilai tetap | switch |
Rentang nilai, misalnya >= 80 dan >= 70 | rantai if |
| Kondisi gabungan beberapa variabel | rantai if |
| Nilai yang tidak cocok perlu jalur khusus | default atau else |
Aturan praktisnya, pilih bentuk yang membuat daftar kasusnya paling mudah dibaca. Rantai if unggul saat bentuk kondisinya beragam, sedangkan switch unggul saat nilai kasusnya beragam. Keduanya menghasilkan jalur yang sama, jadi perbedaannya terletak pada kejelasan, bukan pada kemampuan.
Kesalahan umum#
- Mengandalkan truthiness untuk nilai yang sah berupa
0atau string kosong. Pemeriksaanif (jumlah)menganggap jumlah 0 sama dengan ketiadaan data, padahal keduanya berbeda makna. Bedakan dengan=== null,=== undefined, atau ambil nilai cadangan lewat??. - Lupa
breakdi dalamswitch. Eksekusi jatuh kecaseberikutnya tanpa peringatan, dan hasilnya salah secara diam-diam. Biasakan menulisbreakdi setiapcase, lalu gabungkancasehanya lewat badan kosong yang memang disengaja. - Mengira truthiness menahan ReferenceError. Pengecekan
if (nama)tetap memunculkan error bila variabelnamatidak pernah dideklarasikan. Periksa keberadaannya lebih dulu dengantypeof nama !== "undefined"bila variabelnya sendiri belum pasti ada.
Ringkasan#
- Rantai
if,else if, danelsememeriksa kondisi berurutan dari atas dan berhenti pada kondisi pertama yang benar, sehingga urutan kondisi menjadi bagian dari logika. - Daftar nilai falsy tetap dan pendek, yaitu
false,0,-0,0n, string kosong,null,undefined, danNaN, sedangkan nilai lain dianggap truthy dan nilai cadangan yang aman ditulis dengan??. switchmembandingkan satu ekspresi dengan===terhadap sejumlahcase, berhenti padabreak, dan menampung sisa nilai didefault.breakyang hilang memicu fallthrough tanpa error, sedangkan penggabungancasedengan badan kosong adalah fallthrough yang disengaja.
Referensi#
- if…else — MDN — dokumentasi resmi percabangan if, else if, dan else beserta contohnya.
- switch — MDN — aturan case, break, dan default pada switch menurut dokumentasi resmi.
- Conditional branching — javascript.info — penjelasan truthiness dan pola if else dengan contoh yang bisa dicoba.