Masukkan Password
88 Operator Nullish Coalescing
Lecture ini membahas Nullish Coalescing Operator (??), yang sangat erat hubungannya dengan lecture sebelumnya tentang Optional Chaining (?.).
Inti paling pentingnya:
??digunakan untuk memberikan nilai cadangan (default) hanya ketika nilai di sebelah kiri adalahnullatauundefined.
Materi ini memang sering membingungkan karena bentuknya mirip dengan ||. Padahal aturan keduanya berbeda. Lecture juga menggunakan contoh products dari lecture sebelumnya.
1. Apa itu Nullish Coalescing Operator?
Namanya memang panjang:
Nullish Coalescing Operator
Syntax:
??
Contoh:
const name = userName ?? "Unknown";
Cara membacanya:
“Kalau
userNamepunya nilai yang bukannulldan bukanundefined, gunakanuserName. KalauuserNameadalahnullatauundefined, gunakan"Unknown".”
Secara sederhana:
A ?? B
↓
Apakah A null/undefined?
↙ ↘
YA TIDAK
↓ ↓
B A
Jadi:
20 ?? "Hello"
hasilnya:
20
Sedangkan:
null ?? "Hello"
hasilnya:
Hello
Dan:
undefined ?? "Hello"
hasilnya:
Hello
2. Kenapa kita membutuhkan ???
Sebenarnya kita sudah punya ||.
Misalnya:
const height = a || b;
Kenapa tidak selalu pakai || saja?
Karena || dan ?? mempunyai definisi yang berbeda tentang kapan harus menggunakan nilai cadangan.
||
Mengecek truthy/falsy.
??
Hanya mengecek:
null
undefined
Ini perbedaan paling penting dalam lecture.
3. Mari mulai dari ||
Kita sudah belajar sebelumnya bahwa:
A || B
akan mengembalikan:
nilai truthy pertama.
Contoh:
20 || "Hello"
20 adalah truthy.
Maka:
20
Kalau:
undefined || "Hello"
undefined adalah falsy.
Maka:
"Hello"
Kalau:
null || "Hello"
null adalah falsy.
Maka:
"Hello"
Sampai sini || dan ?? terlihat sama.
Masalahnya muncul ketika kita menggunakan nilai falsy lainnya.
4. Nilai falsy yang perlu kamu ingat
Dalam JavaScript, nilai falsy adalah:
false
0
""
null
undefined
NaN
Jadi:
0 || "Default"
hasilnya:
"Default"
Karena:
0 = falsy
Begitu juga:
"" || "Default"
hasilnya:
"Default"
Karena empty string juga falsy.
5. Di sinilah ?? berbeda
Sekarang:
0 ?? "Default"
Hasilnya:
0
Kenapa?
Karena ?? tidak peduli bahwa 0 adalah falsy.
Dia hanya bertanya:
“Apakah nilainya
nullatauundefined?”
0 bukan keduanya.
Maka:
0
dikembalikan.
Begitu juga:
"" ?? "Default"
hasilnya:
""
Karena empty string bukan null dan bukan undefined.
6. Ini perbedaan utama || vs ??
Perhatikan tabel ini:
| A | A || "Default" | A ?? "Default" |
|—|—|—|
| 20 | 20 | 20 |
| "John" | "John" | "John" |
| null | "Default" | "Default" |
| undefined | "Default" | "Default" |
| 0 | "Default" | 0 |
| "" | "Default" | "" |
| false | "Default" | false |
| NaN | "Default" | NaN |
Jadi:
|| → peduli TRUTHY/FALSY
?? → peduli NULL/UNDEFINED
Kalau kamu mengingat satu tabel saja, ingat tabel ini.
7. Contoh dari lecture: A dan B
Lecture membuat:
let a = 20;
let b = "height not defined";
Kemudian ingin:
Kalau
aada, gunakana. Kalauatidak ada (null/undefined), gunakanb.
Tanpa ??, kita bisa membuat kondisi:
let height;
if (a !== null && a !== undefined) {
height = a;
} else {
height = b;
}
Tetapi ini cukup panjang.
Dengan ternary bisa dibuat:
let height =
a !== null && a !== undefined
? a
: b;
Lebih pendek.
Tetapi masih cukup panjang.
Dengan ??:
let height = a ?? b;
Selesai.
Inilah salah satu alasan ?? berguna.
8. Cara kerja a ?? b
Misalnya:
let a = 20;
let b = "height not defined";
let height = a ?? b;
JavaScript mengecek:
a = 20
Apakah 20 null?
→ Tidak
Apakah 20 undefined?
→ Tidak
Maka gunakan a.
Hasil:
height === 20
Kalau:
let a = null;
maka:
a = null
Apakah null?
→ YA
Gunakan b.
Hasil:
height === "height not defined"
Kalau:
let a;
let height = a ?? b;
Karena a dideklarasikan tetapi belum diberi nilai:
a === undefined
Maka:
undefined
↓
??
↓
gunakan b
Hasilnya:
"height not defined"
9. Jadi rumus sederhananya
A ?? B
berarti:
Kalau A !== null && A !== undefined
→ gunakan A
Kalau A === null || A === undefined
→ gunakan B
Ini jauh lebih tepat daripada menghafalkan nama panjang operatornya.
10. Kenapa || tidak selalu cocok?
Bayangkan kita punya jumlah stok:
let stock = 0;
0 memiliki arti:
Barang memang habis.
Kita ingin:
let displayedStock = stock ?? 10;
Hasil:
0
Ini benar.
Tetapi kalau menggunakan:
let displayedStock = stock || 10;
hasilnya:
10
Padahal stok sebenarnya 0.
Ini bisa menjadi bug.
Karena || menganggap:
0 = falsy
dan langsung menggunakan default.
Sedangkan ?? mengatakan:
“Saya hanya menggunakan default kalau benar-benar tidak ada nilai (
null/undefined).”
11. Contoh lain: umur
Misalnya:
let age = 0;
Secara bisnis mungkin 0 adalah nilai yang valid.
Kalau:
const userAge = age || 18;
hasilnya:
18
Padahal kita memiliki:
age = 0
Dengan:
const userAge = age ?? 18;
hasil:
0
Lebih tepat jika 0 memang nilai valid.
12. Empty string juga penting
Misalnya form:
let username = "";
Kalau:
let result = username ?? "Guest";
hasil:
""
Karena:
"" !== null
"" !== undefined
Tetapi:
let result = username || "Guest";
hasil:
"Guest"
Karena:
"" = falsy
Jadi kamu harus menentukan kebutuhan program.
Kalau yang kamu maksud:
“Gunakan default hanya jika datanya benar-benar tidak ada.”
→ gunakan ??.
Kalau yang kamu maksud:
“Gunakan default jika datanya kosong/falsy.”
→ || mungkin lebih cocok.
13. Hubungannya dengan Optional Chaining ?.
Nah, ini bagian yang sangat penting karena lecture ini langsung melanjutkan materi sebelumnya.
Kita sebelumnya belajar:
product?.features?.ram
Optional chaining menghasilkan:
nilai RAM
atau
undefined
Misalnya product kedua tidak punya features:
product?.features?.ram
hasilnya:
undefined
Tapi mungkin kita tidak mau menampilkan undefined di layar.
Kita ingin:
""
atau:
"RAM not available"
Nah, kita bisa menggabungkan:
product?.features?.ram ?? ""
Ini kombinasi yang sangat berguna.
14. Baca ?. dan ?? sebagai dua langkah
Misalnya:
product?.features?.ram ?? ""
Jangan melihatnya sebagai satu kode rumit.
Pecah menjadi dua:
Langkah 1 — ?.
product?.features?.ram
Artinya:
“Coba ambil RAM dengan aman.”
Hasilnya bisa:
16GB
atau:
undefined
Langkah 2 — ??
hasil ?? ""
Artinya:
“Kalau hasilnya
nullatauundefined, ganti dengan string kosong.”
Jadi:
product?.features?.ram
↓
aman diakses
↓
dapat 16GB / undefined
↓
??
↓
undefined → ""
16GB → 16GB
15. Ini kombinasi yang sangat penting
Kamu bisa mengingatnya seperti ini:
?. → AMANKAN AKSES
?? → BERIKAN DEFAULT
Contoh:
user?.address?.city ?? "Unknown"
Artinya:
“Coba ambil city dari address dengan aman. Kalau city ternyata
nullatauundefined, gunakanUnknown.”
16. Kenapa lecture menggunakan tanda kurung?
Lecture kemudian menunjukkan kasus seperti:
console.log(
"RAM: " +
product?.features?.ram ?? ""
);
Ini bisa membingungkan karena operator precedence.
Secara konsep, kita ingin:
(product?.features?.ram) ?? ""
bukan:
("RAM: " + product?.features?.ram) ?? ""
Karena tujuan kita adalah memberikan default terhadap hasil optional chaining.
Maka gunakan parentheses:
console.log(
"RAM: " + (product?.features?.ram ?? "")
);
Ini jauh lebih jelas.
17. Kenapa ini menghasilkan string kosong?
Misalnya:
product?.features?.ram
menghasilkan:
undefined
Kemudian:
undefined ?? ""
hasilnya:
""
Jadi ketika digabung:
"RAM: " + ""
hasilnya:
"RAM: "
Tidak lagi muncul:
RAM: undefined
18. Contoh lengkap dari project lecture
Misalnya:
products.forEach((product) => {
console.log("Product:", product?.name);
console.log(
"RAM:",
product?.features?.ram ?? ""
);
console.log(
"Year:",
product?.model?.year ?? ""
);
console.log(
"Size:",
product?.details?.size ?? ""
);
console.log("");
});
Sekarang kita punya tiga kemungkinan.
Product 1
Misalnya:
{
name: "Laptop",
features: {
ram: "16GB"
},
model: {
year: 2024
}
}
Hasil:
Product: Laptop
RAM: 16GB
Year: 2024
Size:
Product 2
Misalnya:
{
name: "T-Shirt",
model: null,
details: {
size: "L"
}
}
Maka:
Product: T-Shirt
RAM:
Year:
Size: L
Kenapa RAM kosong?
product.features
↓
undefined
↓
?.ram
↓
undefined
↓
?? ""
↓
""
Kenapa Year kosong?
product.model
↓
null
↓
?.year
↓
undefined
↓
?? ""
↓
""
19. Bagaimana kalau product-nya null?
Lecture juga menggunakan contoh product ketiga:
null
Tanpa optional chaining:
product.name
akan error.
Dengan:
product?.name
hasil:
undefined
Lalu:
product?.name ?? ""
hasil:
""
Jadi:
product = null
↓
product?.name
↓
undefined
↓
?? ""
↓
""
Aman.
20. ?? tidak menggantikan ?.
Ini juga jangan tertukar.
?? tidak membuat akses property menjadi aman.
Misalnya:
user.address.city ?? "Unknown"
Kalau address adalah null, tetap akan error sebelum ?? bisa membantu.
Karena JavaScript harus mengevaluasi:
user.address.city
terlebih dahulu.
Jadi:
user.address.city ?? "Unknown"
bukan safe access.
Kalau address mungkin tidak ada, gunakan:
user.address?.city ?? "Unknown"
Ini pola yang sangat umum.
21. Perbedaan ?. dan ??
| Operator | Fungsi |
|---|---|
?. | Mengakses property dengan aman |
?? | Memberikan default untuk null/undefined |
Contoh:
user?.address?.city ?? "Unknown"
Urutannya:
?. → cari data dengan aman
↓
?? → kalau tidak ada, beri default
22. Bandingkan tiga pendekatan
Tanpa apa-apa
user.address.city
Kalau address null:
❌ ERROR
Optional chaining
user.address?.city
Kalau address null:
✅ undefined
Optional chaining + nullish coalescing
user.address?.city ?? "Unknown"
Kalau address null:
✅ "Unknown"
Jadi:
. → akses biasa
?. → akses aman
?. + ?? → akses aman + default
23. ?? vs || — cara paling mudah mengingatnya
Bayangkan kamu punya:
let value = ...;
||
Bertanya:
“Apakah value ini falsy?”
Kalau iya → pakai kanan.
value || defaultValue
??
Bertanya:
“Apakah value ini null atau undefined?”
Kalau iya → pakai kanan.
value ?? defaultValue
24. Analogi sederhana
Bayangkan kamu punya kotak makanan.
||
Petugas berkata:
“Kalau kotaknya kosong atau dianggap tidak valid, kasih makanan cadangan.”
Jadi:
0 → dianggap kosong
"" → dianggap kosong
false → dianggap kosong
null → dianggap kosong
undefined → dianggap kosong
??
Petugas berkata:
“Saya hanya kasih makanan cadangan kalau memang tidak ada data sama sekali.”
Jadi:
0 → tetap 0
"" → tetap ""
false → tetap false
null → cadangan
undefined → cadangan
25. Hubungan dengan falsy yang sudah kamu pelajari
Sebelumnya kita belajar:
false
undefined
null
""
NaN
0
adalah falsy.
Sekarang tambahkan konsep baru:
Falsy
│
├── false
├── undefined ← ?? peduli
├── null ← ?? peduli
├── ""
├── NaN
└── 0
Jadi ?? hanya mengambil dua anggota dari kelompok falsy:
null
undefined
Sedangkan || memperhatikan semuanya.
26. Contoh penting: false
Misalnya:
let isAdmin = false;
false adalah nilai yang valid.
Kalau:
let result = isAdmin || true;
hasil:
true
Ini mungkin salah.
Karena false berarti:
User memang bukan admin.
Dengan:
let result = isAdmin ?? true;
hasil:
false
Karena false bukan null dan bukan undefined.
27. Contoh penting: 0
let score = 0;
Dengan ||:
score || 100
hasil:
100
Dengan ??:
score ?? 100
hasil:
0
Kalau 0 adalah nilai valid, ?? lebih tepat.
28. Contoh penting: NaN
let result = NaN;
NaN adalah falsy.
Maka:
result || 100
→ 100
Tetapi:
result ?? 100
→ NaN
Karena NaN bukan null dan bukan undefined.
29. Bisa chaining beberapa ??
Kamu juga bisa melakukan:
const value = a ?? b ?? c;
Cara membacanya:
Gunakan
akalau tidak null/undefined. Kalau tidak ada, cobab. Kalaubjuga null/undefined, gunakanc.
Contoh:
const username =
userName ?? displayName ?? "Guest";
Flow:
userName
↓
ada?
┌─┴─┐
YES NO
↓ ↓
pakai displayName
↓
ada?
┌─┴─┐
YES NO
↓ ↓
pakai "Guest"
30. Contoh realistis dalam project CIN/Cinix
Misalnya movie punya image:
movie.image
Kalau image tidak tersedia:
movie.image = null;
Kita bisa menggunakan:
const image =
movie.image ?? "images/not-found.jpg";
Artinya:
image tersedia?
↓
YA → gunakan image
NO (null/undefined)
↓
gunakan not-found.jpg
Tetapi ingat, sebelumnya project kita menggunakan:
image || "images/not-found.jpg"
Keduanya bisa benar tergantung aturan datanya.
Kalau hanya null/undefined yang berarti “tidak ada image”, ?? lebih semantik.
Kalau empty string "" juga ingin dianggap “tidak ada image”, || akan lebih cocok.
31. Perhatikan perbedaan ini
Misalnya:
movie.image = "";
Dengan:
movie.image || "not-found.jpg"
hasil:
not-found.jpg
Dengan:
movie.image ?? "not-found.jpg"
hasil:
""
Jadi pertanyaannya:
Apakah
""dianggap data yang valid atau dianggap tidak ada?
Itu yang menentukan pilihan operator.
32. Catatan kecil tentang nama operator di caption
Caption beberapa kali menyebutnya seperti:
“null equalizing”, “null initializing”, atau “nullizing operator”.
Nama yang benar dan umum adalah:
Nullish Coalescing Operator
dan syntax-nya:
??
Jadi sebaiknya kamu biasakan menyebutnya:
Nullish Coalescing Operator (
??)
33. Catatan teknis: ?? bukan sekadar versi pendek ||
Ini penting.
Jangan berpikir:
?? = || yang lebih baru
Tidak persis begitu.
Keduanya mempunyai kriteria berbeda.
0 || 10
// 10
0 ?? 10
// 0
Jadi mereka bisa menghasilkan hasil yang berbeda secara sengaja.
34. Cara memilih || atau ??
Gunakan pertanyaan ini:
Pertanyaan 1
“Kalau nilainya
0, apakah saya tetap ingin0?”
Kalau ya, pertimbangkan:
??
Pertanyaan 2
“Kalau nilainya
"", apakah saya tetap ingin string kosong?”
Kalau ya, pertimbangkan:
??
Pertanyaan 3
“Saya hanya ingin default kalau nilainya benar-benar
nullatauundefined?”
Gunakan:
??
Pertanyaan 4
“Saya ingin semua nilai falsy dianggap tidak valid?”
Gunakan:
||
35. Cheat Sheet
NULLISH COALESCING
==================
Syntax:
A ?? B
Artinya:
Kalau A null/undefined → B
Selain itu → A
Contoh:
20 ?? 10
// 20
null ?? 10
// 10
undefined ?? 10
// 10
0 ?? 10
// 0
"" ?? "Hello"
// ""
false ?? true
// false
36. Cheat sheet || vs ??
|| ??
---------------------------------------
null B B
undefined B B
0 B 0
"" B ""
false B false
NaN B NaN
"Hello" "Hello" "Hello"
20 20 20
Mental model:
|| → "Apakah nilainya FALSY?"
?? → "Apakah nilainya NULLISH?"
Nullish = null atau undefined.
37. Kombinasi paling penting dari dua lecture terakhir
Kamu sekarang sudah punya pasangan yang sangat berguna:
user?.profile?.name ?? "Unknown"
Baca:
user?
↓
?. → aman mengakses
profile?
↓
?. → aman mengakses
name
↓
dapat nilai / undefined
??
↓
kalau null/undefined
gunakan "Unknown"
Jadi:
?.= jangan error saat mengambil data yang mungkin tidak ada.
??= kasih nilai default kalau data tersebut memangnullatauundefined.
38. Hubungkan dengan materi sebelumnya
Kalau kita susun semua operator yang sudah kamu pelajari:
JavaScript Modern Syntax
│
├── ?. Optional Chaining
│ ↓
│ akses property dengan aman
│
├── ?? Nullish Coalescing
│ ↓
│ kasih default untuk null/undefined
│
├── || Logical OR
│ ↓
│ cari nilai truthy pertama
│
├── ... Spread
│ ↓
│ menyebarkan isi
│
├── ... Rest
│ ↓
│ mengumpulkan sisa
│
└── Destructuring
↓
mengambil data berdasarkan
posisi/property
Dan dua yang baru ini bisa bekerja sama:
const city =
user?.address?.city ?? "Unknown";
Ini pola yang sangat sering kamu temui ketika nanti bekerja dengan data API atau object yang strukturnya tidak selalu lengkap.
39. Inti lecture dalam satu kalimat
Kalau kamu hanya mengingat satu hal:
??mengembalikan nilai kiri selama nilai tersebut bukannulldan bukanundefined; kalau kirinull/undefined, barulah nilai kanan digunakan sebagai default.
Dan jangan lupa pasangan dengan lecture sebelumnya:
?. → "AMAN GAK KALAU DATA INI TIDAK ADA?"
?? → "KALAU TIDAK ADA, MAU DIGANTI APA?"
Contoh final:
const ram =
product?.features?.ram ?? "RAM not available";
Artinya:
1. Coba ambil product
2. Coba ambil features
3. Coba ambil ram
4. Kalau salah satu optional access menghasilkan
null/undefined → gunakan "RAM not available"
Jadi ?. dan ?? bukan saingan—mereka justru sering menjadi pasangan.