Soal 1Tulis let couponCode; dan bacalah tanpa meng-assign value. Berapa value variable itu?
null dan undefined — Membaca dengan Aman Pakai ?. dan ??
Pelajari beda null dan undefined, lalu cara membaca object nested dengan aman lewat ?. dan ??.
Menampilkan data order dari server, kamu akan menemui address yang tidak pernah diisi, atau metode pembayaran yang belum dipilih. JavaScript punya 2 value untuk kondisi "tidak ada apa-apa di sini" ini — undefined dan null — dan pembacaan yang gagal menghentikan proses dengan TypeError.
Artikel ini membahas perbedaan keduanya, membaca lewat langkah yang hilang tanpa berhenti, dan menerapkan default value saat sesuatu hilang.
2 Value yang Berarti Tidak Ada Apa-Apa — undefined dan null
undefined (value yang otomatis diisi JavaScript saat belum ada yang di-assign) muncul dengan sendirinya — kamu tidak perlu meng-assign-nya sendiri. Kamu sudah melihatnya dikembalikan dari membaca melewati akhir array atau key object yang tidak terdaftar, dan variable yang cuma dideklarasikan juga masuk kategori ini.
- Variable yang cuma dideklarasikan, tanpa pernah diberi value, seperti
let couponCode; - Key yang tidak terdaftar di object, seperti
order.customer(sudah dilihat sebelumnya) - Index di luar jangkauan pada array 2 element, seperti
tags[5](sudah dilihat sebelumnya)
null (value yang sengaja di-assign penulisnya untuk menandakan kekosongan), di sisi lain, tidak pernah muncul dengan sendirinya. Saat kamu mau ketiadaan value itu sendiri jadi data — "belum ada shipping address yang dipilih," "tidak ada coupon yang dipakai" — kamu meng-assign null sendiri.
JSON yang kembali dari API juga bisa membawa null untuk menandakan sebuah field kosong.
Karena keduanya value berbeda, === mengembalikan false saat membandingkannya. ==, meski begitu, memperlakukan keduanya sebagai sama dan mengembalikan true.
Saat menulis pengecekan, sengaja pilih mana yang kamu maksud dan cek hanya sisi itu, seperti === null, atau serahkan sepenuhnya ke ?. dan ??, yang dibahas mulai dari sini.
let couponCode; // cuma dideklarasikan, tanpa value
console.log(couponCode); // undefined
const order = { orderId: "ORD-1105", total: 12800 };
console.log(order.customer); // undefined (key yang tidak terdaftar)
const tags = ["Limited", "Preorder"];
console.log(tags[5]); // undefined (index di luar jangkauan)
// null di-assign oleh penulisnya
let shippingAddress = null; // belum ada shipping address yang dipilih
console.log(shippingAddress); // null
console.log(shippingAddress === undefined); // false (keduanya value berbeda)
console.log(shippingAddress == undefined); // true (== memperlakukan keduanya sama)
Tidak Berhenti Saat Langkah Nested Hilang — Optional Chaining ?.
Data yang kembali dari API tidak selalu punya tiap field terisi. Kode yang membaca dalam, seperti order.customer.address.city, berhenti begitu ada 1 order yang tidak punya address di tengah jalan.
Inilah saatnya kamu mau pembacaannya sendiri tidak gagal — terus jalan sebagai "tidak ada apa-apa" sebagai gantinya.
Saat order.customer.address adalah undefined, mencoba membaca .city setelahnya melempar TypeError: Cannot read properties of undefined (reading 'city'). Langkah pembacaan ke-1 lancar, tapi berhenti di ke-2.
Untuk itulah optional chaining ada (operator ?., yang mengembalikan undefined tanpa membaca lebih jauh kalau sisi kirinya null atau undefined). Tulis address?.city, dan .city hanya dibaca kalau address punya value — kalau tidak, pembacaannya berhenti di situ dan mengembalikan undefined.
Saat mengirim key lewat [], tulis sebagai ?.[field].
const order = {
orderId: "ORD-1105",
customer: { name: "Ryan Cole" },
};
// address hilang, jadi membaca city setelahnya akan berhenti
// console.log(order.customer.address.city);
// TypeError: Cannot read properties of undefined (reading 'city')
// Sisipkan ?. dan pembacaannya berhenti, mengembalikan undefined
console.log(order.customer.address?.city); // undefined
// Kalau ada value-nya, terus jalan seperti biasa
console.log(order.customer.name); // Ryan Cole
// Kirim key lewat variable dengan ?.[]
const field = "city";
console.log(order.customer.address?.[field]); // undefined
Pakai Ini Hanya di Field yang Memang Bisa Hilang
Taruh ?. di tiap langkah, dan bahkan nama key yang typo bisa lolos jadi undefined tanpa error. Lewati field yang dijamin ada, dan pakai ini hanya tepat sebelum field yang memang bisa hilang secara sah — dengan begitu error yang sebenarnya kamu mau tangkap tetap menghentikan eksekusi.
Menyiapkan Default Value — ?? vs ||
Daripada menampilkan undefined polos saat sebuah field hilang, biasanya kamu mau menampilkan default — "Guest," "20 item."
Pakai || untuk ini, meski begitu, kadang value yang sebenarnya ada malah diganti dengan default-nya. Jumlah stok 0, atau field catatan kosong, adalah contohnya.
null dan undefined bersama disebut nullish. Pakai Nullish coalescing operator (operator ??, yang mengembalikan sisi kanan hanya kalau sisi kiri nullish), dan 0, string kosong, atau false tetap persis apa adanya.
|| mengembalikan sisi kanan kapan pun sisi kirinya falsy, jadi dia tidak bisa membedakan "tidak ada value" dari "value-nya 0." Saat tujuanmu menerapkan default, ?? menghindari penggantian yang tidak diinginkan itu.
0. ?? hanya mengganti null dan undefined, jadi 0 tetap jadi value-nya.| Value Sisi Kiri | Yang Dikembalikan || | Yang Dikembalikan ?? |
|---|---|---|
| null | default-nya | default-nya |
| undefined | default-nya | default-nya |
| 0 | default-nya | tetap 0 |
| string kosong | default-nya | tetap string kosong |
| false | default-nya | tetap false |
const settings = { displayName: null, itemsPerPage: 0 };
// ?? mengembalikan sisi kanan hanya kalau kiri null atau undefined
console.log(settings.displayName ?? "Guest"); // Guest
console.log(settings.itemsPerPage ?? 20); // 0 (tetap apa adanya)
// || mengembalikan sisi kanan kapan pun kiri falsy, jadi bahkan 0 pun diganti
console.log(settings.itemsPerPage || 20); // 20
// Key yang tidak terdaftar jatuh ke default keduanya
console.log(settings.language ?? "en"); // en
console.log(settings.language || "en"); // en
Perhatikan menulis ?? dan || bersebelahan tanpa tanda kurung, seperti displayName ?? "Guest" || "Anonymous", adalah syntax error — JavaScript tidak bisa memutuskan mana yang dievaluasi dulu. Untuk memakai keduanya, pisahkan dengan tanda kurung, seperti (displayName ?? "Guest") || "Anonymous".
Jangan Biarkan Default Menghapus 0 atau String Kosong
Jumlah stok 0, discount rate 0, catatan kosong — semuanya terhitung "ada value-nya." Terapkan default dengan ||, dan karena semuanya falsy, mereka diganti dengan default-nya, membuat ketidakcocokan seperti item habis stok tampil seolah masih ada. Pakai ?? saat yang kamu pedulikan cuma apakah ada value sama sekali.
Tidak Memanggil Sesuatu yang Tidak Ada — Pemanggilan ?.()
Dalam pemrosesan order, kadang kamu menyimpan "apa yang dilakukan saat sukses" dan "apa yang dilakukan saat gagal" di dalam sebuah object, memanggilnya saat perlu. Panggil field yang belum diisi apa pun, meski begitu, dan itu berhenti dengan TypeError: handlers.onError is not a function — jadi kamu perlu cara memanggilnya hanya saat itu benar-benar ada.
Function yang dibahas di artikel 3 juga bisa hidup di dalam object sebagai value sebuah property. () => ... di contoh berikutnya adalah syntax untuk membuat function di tempat — syntax itu sendiri dibahas di kategori syntax, jadi di sini cukup fokus pada bagaimana hasilnya berubah tergantung apakah sebuah function ada di property-nya.
Panggil property yang mungkin memegang function sebagai handlers.onError?.(), dan saat onError adalah null atau undefined, pemanggilannya dilewati dan undefined kembali sebagai gantinya.
undefined tanpa memanggil apa pun kalau null. Panggil tanpa ?. dan itu berhenti dengan TypeError.const handlers = {
onSuccess: () => console.log("Order confirmed"),
onError: null,
};
// Ada function-nya, jadi dipanggil
handlers.onSuccess?.(); // Order confirmed
// null, jadi pemanggilannya dilewati dan undefined kembali
console.log(handlers.onError?.()); // undefined
// Memanggil tanpa ?. menghentikan eksekusi
// handlers.onError();
// TypeError: handlers.onError is not a function
Cek Pemahaman
Jawab setiap pertanyaan satu per satu.
Soal 2Saat sisi kiri ?. adalah null atau undefined, apa yang terjadi pada sisa rantainya?
Soal 3Dengan const discountRate = 0;, apa yang dikembalikan discountRate || 5 dan discountRate ?? 5 masing-masing?