Data yang masuk dari formulir web dan dari parameter URL selalu berupa string. Jadi ketika pengguna mengisi usia 18, program menerima teks "18" — dan teks itu tidak identik dengan angka 18. Jika kita memeriksa usia === 18 dan hasilnya selalu false, bug-nya bukan pada nilai, melainkan pada tipe. Di sinilah dua operator kesetaraan JavaScript memainkan peran berbeda, dan salah memilihnya menjadi salah satu sumber bug paling umum bagi pemula.
Chapter penutup section ini membedakan === (strict equality) dan == (loose equality), membuktikan perilaku keduanya pada kasus-kasus paling penting, dan menjelaskan mesin di balik layar: type coercion, konversi tipe yang terjadi tanpa suara.
Dua Operator Kesamaan #
Operator === menanyakan “apakah nilai dan tipenya sama-sama identik?”. Operator == menanyakan versi longgar: “apakah setelah dikonversi ke tipe yang sama, nilainya sama?”. Perbedaan satu tanda sama dengan itu berdampak besar:
| Ekspresi | Hasil | Penjelasan |
|---|---|---|
5 == 5 | true | Nilai dan tipe sama |
5 === 5 | true | Sama seperti di atas |
5 == "5" | true | "5" dikonversi menjadi 5 sebelum dibandingkan |
5 === "5" | false | Tipe berbeda: number versus string |
null == undefined | true | Pasangan khusus yang setara pada == |
null === undefined | false | Tipe berbeda: null versus undefined |
0 == false | true | false dikonversi menjadi 0 |
0 === false | false | Tipe berbeda: number versus boolean |
NaN === NaN | false | NaN tidak sama dengan nilai apa pun |
Baris terakhir patut digarisbawahi: NaN bahkan tidak sama dengan dirinya sendiri. Karena itu nilai === NaN tidak akan pernah true, dan pemeriksaan NaN harus memakai fungsi khusus Number.isNaN() — sudah kita gunakan di chapter Arithmetic Operators.
Koersi: Konversi yang Terjadi Senyap #
Mekanisme == bisa dirangkum: engine melihat kedua tipe; bila berbeda, engine mengonversinya mengikuti aturan bawaan spesifikasi, lalu membandingkan hasilnya. Aturan-aturan itu terasa wajar pada kasus sederhana ("5" menjadi angka 5), tetapi makin sulit ditebak pada kombinasi lain:
console.log("" == 0);
console.log("0" == 0);
console.log("0" == false);
console.log(true == 1);Output yang Dihasilkan:
true
true
true
trueString kosong "", string "0", boolean false, dan angka 0 — empat nilai yang secara makna berbeda-beda — semuanya dianggap sama oleh ==. Ada satu pengecualian yang terasa rapi di tengah aturan longgar ini: null hanya setara dengan undefined (dan dirinya sendiri). Pemeriksaan null == 0 menghasilkan false, begitu pula undefined == 0. Konversi senyap semacam ini berlaku bukan hanya pada ==; operator perbandingan < dan > dari chapter Comparison Operators pun melakukan koersi ketika kedua sisi bertipe beda — alasan tambahan untuk selalu menyamakan tipe sebelum membandingkan.
Menguji Perilaku Secara Nyata #
Berkas berikut merangkum semua kasus penting dari tabel di atas. Jalankan dan cocokkan tiap baris dengan dugaan kita:
// uji-kesamaan.js
// Membuktikan perbedaan == dan === serta perilaku NaN.
console.log(5 == 5);
console.log(5 === 5);
// == melakukan konversi tipe terlebih dahulu.
console.log(5 == "5");
console.log(5 === "5");
// null dan undefined saling setara pada ==, tetapi tidak pada ===.
console.log(null == undefined);
console.log(null === undefined);
// false dikonversi menjadi 0 sebelum dibandingkan.
console.log(0 == false);
console.log(0 === false);
// NaN tidak sama dengan nilai apa pun, termasuk dirinya sendiri.
console.log(NaN === NaN);
console.log(Number.isNaN(NaN));Output yang Dihasilkan:
true
true
true
false
true
false
true
false
false
trueMari kita telaah baris-baris pentingnya:
- Baris 4–5 (
5 == 5dan5 === 5): tanpa perbedaan tipe, kedua operator sepakat — keduanyatrue. - Baris 8 (
console.log(5 == "5");):==mengonversi"5"menjadi angka5, lalu membandingkannya; hasilnyatrue. - Baris 9 (
console.log(5 === "5");):===berhenti di perbedaan tipe tanpa mencoba mengonversi; hasilnyafalse. Dua baris berdampingan ini adalah inti chapter. - Baris 12–13 (
null == undefineddannull === undefined):==menganggap keduanya setara (keduanya penanda “tidak ada nilai”), sedangkan===tetap melihat tipe yang berbeda dan menghasilkanfalse. - Baris 16–17 (
0 == falsedan0 === false):falsedikonversi menjadi0oleh==;===menolaknya karena boolean dan number adalah tipe berbeda. - Baris 20 (
console.log(NaN === NaN);): hasilnyafalse— bukti langsung bahwaNaNtidak bisa dibandingkan dengan dirinya sendiri, apalagi dengan nilai lain. - Baris 21 (
console.log(Number.isNaN(NaN));): fungsiNumber.isNaN()menghasilkantruehanya untukNaN— satu-satunya cara andal mendeteksinya.
Kebalikannya: !== dan != #
Kedua operator kesetaraan punya pasangan negasi: !== (strict inequality) dan != (loose inequality). Kebalikannya konsisten — apa yang dikatakan sama oleh ==, dikatakan berbeda oleh !=, begitu pula pasangan === dan !==:
console.log(5 !== "5");
console.log(5 != "5");Output yang Dihasilkan:
true
falseBaris pertama memakai !==: karena 5 dan "5" berbeda tipe, !== menyatakannya berbeda dan menghasilkan true. Baris kedua memakai !=: konversi tipe menyamakan 5 dan "5" lebih dulu, sehingga hasilnya false. Aturan pemilihannya sama persis dengan kesetaraan — pilih versi strict agar konversi tipe tidak terjadi senyap.
Aturan Praktis: Selalu === #
Aturan yang berlaku di hampir seluruh kode modern: gunakan === dan !== untuk semua pemeriksaan kesamaan. Operator === membuat konversi tipe jadi masalah yang terlihat, bukan tersembunyi — bila data dari formulir datang sebagai string "18", pemeriksaan usia === 18 akan gagal dengan jelas, memberi kita kesempatan mengonversi nilainya secara eksplisit (dengan Number(), seperti di section Values dan Types) alih-alih mengandalkan koersi senyap.
Ada satu pengecualian kecil yang diakui luas: pola nilai == null untuk memeriksa “nilai ini null atau undefined sekaligus” memanfaatkan pasangan khusus di tabel. Pola itu sah, tetapi menulis nilai === null || nilai === undefined jauh lebih eksplisit — dan konsisten dengan aturan utamanya. Dengan aturan === ini, section Operators tuntas: kita kini bisa menghitung, membandingkan, menggabungkan kondisi, memberi nilai cadangan, mengakses data bertingkat, memilih nilai dengan ternary, dan membaca urutan evaluasi dengan benar.
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
uji-kesamaan.js
Unduh berkas// uji-kesamaan.js
// Membuktikan perbedaan == dan === serta perilaku NaN.
console.log(5 == 5);
console.log(5 === 5);
// == melakukan konversi tipe terlebih dahulu.
console.log(5 == "5");
console.log(5 === "5");
// null dan undefined saling setara pada ==, tetapi tidak pada ===.
console.log(null == undefined);
console.log(null === undefined);
// false dikonversi menjadi 0 sebelum dibandingkan.
console.log(0 == false);
console.log(0 === false);
// NaN tidak sama dengan nilai apa pun, termasuk dirinya sendiri.
console.log(NaN === NaN);
console.log(Number.isNaN(NaN));