Operator mana yang sama dengan (== vs ===) yang harus digunakan dalam perbandingan JavaScript?

5665

Saya menggunakan JSLint untuk melihat JavaScript, dan mengembalikan banyak saran untuk menggantikan ==(dua tanda sama dengan) dengan ===(tiga tanda sama dengan) ketika melakukan hal-hal seperti membandingkan idSele_UNVEHtype.value.length == 0di dalam sebuah ifpernyataan.

Apakah ada manfaat kinerja untuk mengganti ==dengan ===?

Setiap peningkatan kinerja akan disambut karena ada banyak operator pembanding.

Jika tidak ada konversi jenis yang terjadi, apakah akan ada peningkatan kinerja ==?

bcasp
sumber
134
Untuk siapa mungkin tertarik pada subjek yang sama === vs ==, tetapi dalam PHP, dapat membaca di sini: stackoverflow.com/questions/2401478/why-is-faster-than-in-php/…
Marco Demaio
257
Hanya dalam kasus orang bertanya-tanya pada tahun 2012: ===adalah cara lebih cepat dari ==. jsperf.com/comparison-of-comparisons
Ry-
25
@minitech seharusnya karena tidak melakukan konversi tipe
Umur Kontacı
19
@minitech, saya ragu ada orang yang akan membuat aplikasi mereka terasa lebih cepat dengan menggunakan ===lebih ==. Faktanya, benchmark tidak menunjukkan perbedaan besar antara keduanya di browser modern. Secara pribadi, saya biasanya menggunakan di ==mana-mana kecuali saya benar-benar membutuhkan kesetaraan yang ketat.
laurent
5
Inilah bagian dari pembicaraan Crockford JS The Good Parts di mana ia membahas ===dan ==operator: youtube.com/… Jika tidak dimainkan, maka pukul 15:20
davidhiggins

Jawaban:

6486

Operator kesetaraan yang ketat ( ===) berperilaku identik dengan operator kesetaraan abstrak ( ==) kecuali tidak ada konversi tipe yang dilakukan, dan jenisnya harus sama agar dianggap sama.

Referensi: Tutorial Javascript: Operator Perbandingan

The ==Operator akan membandingkan kesetaraan setelah melakukan setiap konversi tipe yang diperlukan . The ===Operator akan tidak melakukan konversi, jadi jika dua nilai yang bukan tipe yang sama ===hanya akan kembali false. Keduanya sama-sama cepat.

Mengutip JavaScript luar biasa Douglas Crockford : The Good Parts ,

JavaScript memiliki dua set operator kesetaraan: ===dan !==, dan si kembar jahat ==dan !=. Yang bagus bekerja seperti yang Anda harapkan. Jika kedua operan memiliki tipe yang sama dan memiliki nilai yang sama, maka ===hasilkan truedan !==hasilkan false. Si kembar jahat melakukan hal yang benar ketika operan dari jenis yang sama, tetapi jika mereka dari jenis yang berbeda, mereka berusaha untuk memaksa nilai-nilai itu. aturan-aturan yang dengannya mereka melakukan hal itu rumit dan tidak dapat dilupakan. Ini adalah beberapa kasus menarik:

'' == '0'           // false
0 == ''             // true
0 == '0'            // true

false == 'false'    // false
false == '0'        // true

false == undefined  // false
false == null       // false
null == undefined   // true

' \t\r\n ' == 0     // true

Tabel Perbandingan Kesetaraan

Kurangnya transitivitas mengkhawatirkan. Saran saya adalah jangan pernah menggunakan si kembar jahat. Sebaliknya, selalu gunakan ===dan !==. Semua perbandingan hanya menunjukkan produk falsedengan ===operator.


Memperbarui:

Poin yang bagus disampaikan oleh @Casebash dalam komentar dan dalam jawaban @Phillipe Laybaert mengenai objek. Untuk benda, dan bertindak secara konsisten satu sama lain (kecuali dalam kasus khusus).=====

var a = [1,2,3];
var b = [1,2,3];

var c = { x: 1, y: 2 };
var d = { x: 1, y: 2 };

var e = "text";
var f = "te" + "xt";

a == b            // false
a === b           // false

c == d            // false
c === d           // false

e == f            // true
e === f           // true

Kasus khusus adalah ketika Anda membandingkan primitif dengan objek yang mengevaluasi ke primitif yang sama, karena yang toStringatau valueOfmetode. Sebagai contoh, perhatikan perbandingan string primitif dengan objek string yang dibuat menggunakan Stringkonstruktor.

"abc" == new String("abc")    // true
"abc" === new String("abc")   // false

Di sini ==operator memeriksa nilai dari dua objek dan kembali true, tetapi ===melihat bahwa mereka bukan tipe yang sama dan kembali false. Yang mana yang benar? Itu benar-benar tergantung pada apa yang Anda coba bandingkan. Saran saya adalah untuk memotong pertanyaan sepenuhnya dan hanya tidak menggunakan Stringkonstruktor untuk membuat objek string dari string literal.

Referensi
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3

Bill the Lizard
sumber
237
=== Tidak lebih cepat jika jenisnya sama. Jika jenisnya tidak sama, === akan lebih cepat karena tidak akan mencoba melakukan konversi.
Bill the Lizard
521
=== Tidak akan pernah lebih lambat dari ==. Mereka berdua melakukan pengecekan tipe, jadi === tidak melakukan apa-apa ekstra dibandingkan dengan ==, tetapi pemeriksaan tipe dapat memungkinkan === untuk keluar lebih cepat ketika tipenya tidak sama.
Bill the Lizard
246
Mengganti semua == /! = Dengan === /! == meningkatkan ukuran file js, maka akan membutuhkan lebih banyak waktu untuk memuat. :)
Marco Demaio
92
"... peraturan yang mereka lakukan itu rumit dan tidak mungkin keliru ..." Sekarang pernyataan seperti itu membuat Anda merasa sangat aman saat memprogram ...
Johan
47
Dari Crockford: "Kurangnya transitivitas mengkhawatirkan." Jika Anda mengembangkan perangkat lunak dan tidak menemukan kurangnya transitivitas dalam operator perbandingan yang mengkhawatirkan, atau jika perbandingan kecepatan antara == dan === atau ukuran file / waktu pengambilan diutamakan dalam pikiran Anda dari determinisme transitif dari perilaku operator perbandingan, Anda mungkin perlu kembali dan memulai lagi.
jinglesthula
1144

Menggunakan ==operator ( Kesetaraan )

true == 1; //true, because 'true' is converted to 1 and then compared
"2" == 2;  //true, because "2" is converted to 2 and then compared

Menggunakan ===operator ( Identity )

true === 1; //false
"2" === 2;  //false

Ini karena operator kesetaraan ==memang tipe paksaan , artinya penerjemah secara implisit mencoba untuk mengkonversi nilai-nilai sebelum membandingkan.

Di sisi lain, operator identitas ===tidak melakukan tipe paksaan , dan karenanya tidak mengkonversi nilai saat membandingkan, dan karenanya lebih cepat (sesuai dengan tes benchmark JS ini ) karena melompati satu langkah.

Kalpesh Rajai
sumber
9
@Software Monkey: bukan untuk tipe nilai (angka, boolean, ...)
Philippe Leybaert
34
Karena tidak ada yang menyebutkan Javascript Equality Table, ini dia: dorey.github.io/JavaScript-Equality-Table
blaze
6
Dalam pernyataan pertama, apakah Anda yakin bahwa 'benar' dikonversi menjadi 1 dan bukan 1 dikonversi menjadi benar?
Shadi Namrouti
2
Dari mana datangnya istilah "kesetaraan" dan "identitas"? Standar tidak menggunakan istilah-istilah itu. Itu disebut =="kesetaraan abstrak" dan itu disebut ==="kesetaraan ketat". Memang menyebut ==segala jenis "kesetaraan" itu mengerikan, karena tidak transitif, tetapi mengapa berdalih? Saya mengambil lebih banyak masalah dengan "identitas"; Saya pikir istilah itu cukup menyesatkan, meskipun "berhasil". Tapi serius, siapa yang menciptakan istilah "identitas"? Saya mencari standar dan tidak dapat menemukannya.
Ray Toal
1
"Identitas" adalah kata yang salah. Perbandingan identitas dalam semua bahasa yang saya gunakan cara satu objek yang sama , yaitu variabel referensi dua menunjuk tidak hanya untuk entitas yang setara, tetapi yang entitas yang sama.
Inigo
724

Representasi gambar yang menarik dari perbandingan kesetaraan antara ==dan ===.

Sumber: http://dorey.github.io/JavaScript-Equality-Table/


var1 === var2

Saat menggunakan ===untuk pengujian kesetaraan JavaScript, semuanya seperti apa adanya. Tidak ada yang dikonversi sebelum dievaluasi.

Evaluasi kesetaraan === di JS


var1 == var2

Saat menggunakan ==untuk pengujian kesetaraan JavaScript, beberapa konversi funky terjadi.

Evaluasi kesetaraan == di JS

Pesan moral dalam cerita:

Gunakan ===kecuali jika Anda sepenuhnya memahami konversi yang terjadi ==.

Merobek
sumber
3
@mfeineadalah maksud Anda === atau! == bukannya == atau! =. Tidak ingin membingungkan
pembuat kode
2
dari pengalaman saya menggunakan tiga sama dengan dapat menyebabkan masalah dan harus dihindari kecuali dipahami sepenuhnya. dua sama menghasilkan hasil yang jauh lebih baik karena 99% dari waktu saya benar-benar tidak ingin jenis sama.
vsync
13
@ vsync: Jika Anda benar-benar tidak ingin jenisnya sama , Anda harus menggunakan tiga sama dengan !
SNag
7
Satu pengecualian: Anda dapat dengan aman menggunakan x == nulluntuk memeriksa apakah xini nullatau undefined.
Andy
1
@ user648026: Pertanyaannya adalah tentang kesetaraan dibandingkan dengan ==vs ===. Huruf besar dan huruf kecil tidak sama, dan akan kembali falsedengan operator ==dan keduanya ===. Juga, kata kunci true, false, undefined, null, Infinityada di JS hanya dalam satu kasus, dan tidak dapat digunakan dalam kasus-kasus atas atau campuran.
SNag
609

Dalam jawaban di sini, saya tidak membaca apa pun tentang apa artinya sama . Beberapa orang akan mengatakan itu ===berarti sama dan berjenis sama , tetapi itu tidak sepenuhnya benar. Ini sebenarnya berarti bahwa kedua operan referensi objek yang sama , atau dalam kasus tipe nilai, memiliki nilai yang sama .

Jadi, mari kita ambil kode berikut:

var a = [1,2,3];
var b = [1,2,3];
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

Hal yang sama di sini:

var a = { x: 1, y: 2 };
var b = { x: 1, y: 2 };
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

Atau bahkan:

var a = { };
var b = { };
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

Perilaku ini tidak selalu jelas. Ada lebih banyak cerita daripada menjadi sama dan menjadi tipe yang sama.

Aturannya adalah:

Untuk tipe nilai (angka):
a === b mengembalikan true jikaadanbmemiliki nilai yang sama dan dari tipe yang sama

Untuk tipe referensi:
a === b mengembalikan true jikaadanbreferensi objek yang sama persis

Untuk string:
a === b mengembalikan true jikaadanbkeduanya string dan berisi karakter yang sama persis


Strings: kasus khusus ...

String bukan tipe nilai, tetapi dalam Javascript mereka berperilaku seperti tipe nilai, jadi mereka akan "sama" ketika karakter dalam string adalah sama dan ketika mereka memiliki panjang yang sama (seperti yang dijelaskan dalam aturan ketiga)

Sekarang menjadi menarik:

var a = "12" + "3";
var b = "123";

alert(a === b); // returns true, because strings behave like value types

Tapi bagaimana dengan ini ?:

var a = new String("123");
var b = "123";

alert(a === b); // returns false !! (but they are equal and of the same type)

Saya pikir string berperilaku seperti tipe nilai? Yah, itu tergantung siapa yang kamu tanyakan ... Dalam hal ini a dan b bukan tipe yang sama. aadalah tipe Object, sedangkan btipe string. Hanya ingat bahwa membuat objek string menggunakan Stringkonstruktor menciptakan sesuatu tipe Objectyang berperilaku sebagai string sebagian besar waktu .

Philippe Leybaert
sumber
6
activa: Saya akan mengklarifikasi, bahwa string sangat sama hanya ketika mereka literal. String baru ("abc") === "abc" salah (menurut penelitian saya).
Lawrence Dol
3
new Number() == "0". Juga di Firefox:(function(){}) == "function () {\n}"
Thomas Eding
3
Terima kasih telah menjelaskan alasannya new String("123") !== "123". Mereka adalah tipe yang berbeda. Sederhana, namun membingungkan.
styfle
21
Stringobjek berperilaku seperti string seperti halnya objek lainnya . new Stringtidak boleh digunakan, karena itu tidak membuat string nyata. Sebuah string nyata dan dapat dibuat dengan string literal atau memanggil Stringsebagai fungsi tanpa new , misalnya:String(0); //"0", Real string, not an object
Esailija
6
Tetapi dalam kasus yang Anda detailkan, operator "==" berperilaku sama persis.
Yaron Levi
270

Izinkan saya menambahkan nasihat ini:

Jika ragu, baca spesifikasinya !

ECMA-262 adalah spesifikasi untuk bahasa scripting yang JavaScript adalah dialeknya. Tentu saja dalam praktiknya itu lebih penting bagaimana peramban yang paling penting berperilaku daripada definisi esoteris tentang bagaimana sesuatu seharusnya ditangani. Tetapi akan sangat membantu untuk memahami mengapa String baru ("a")! == "a" .

Tolong izinkan saya menjelaskan cara membaca spesifikasi untuk memperjelas pertanyaan ini. Saya melihat bahwa dalam topik yang sangat lama ini tidak ada yang punya jawaban untuk efek yang sangat aneh. Jadi, jika Anda dapat membaca spesifikasi, ini akan sangat membantu Anda dalam profesi Anda. Ini adalah keterampilan yang didapat. Jadi, mari kita lanjutkan.

Mencari file PDF untuk === membawa saya ke halaman 56 dari spesifikasi: 11.9.4. Operator Sama Ketat (===) , dan setelah mengarungi spesifik saya menemukan:

11.9.6 Algoritma Perbandingan Kesetaraan Ketat Perbandingan
x === y, di mana x dan y adalah nilai, menghasilkan benar atau salah . Perbandingan semacam itu dilakukan sebagai berikut:
  1. Jika Tipe (x) berbeda dari Tipe (y), return false .
  2. Jika Tipe (x) Tidak Terdefinisi, kembalikan true .
  3. Jika Tipe (x) kosong, kembalikan benar .
  4. Jika Tipe (x) bukan Angka, lanjutkan ke langkah 11.
  5. Jika x adalah NaN , kembalikan salah .
  6. Jika y adalah NaN , kembalikan salah .
  7. Jika x adalah nilai angka yang sama dengan y, kembalikan benar .
  8. Jika x adalah +0 dan y adalah −0, kembalikan true .
  9. Jika x adalah −0 dan y adalah +0, kembalikan true .
  10. Kembali salah .
  11. Jika Tipe (x) adalah String, maka mengembalikan true jika x dan y adalah urutan karakter yang sama (panjang yang sama dan karakter yang sama di posisi yang sesuai); jika tidak, kembalikan salah .
  12. Jika Tipe (x) adalah Boolean, kembalikan benar jika x dan y keduanya benar atau keduanya salah ; jika tidak, kembalikan salah .
  13. Kembalikan benarjika x dan y merujuk ke objek yang sama atau jika mereka merujuk ke objek yang bergabung satu sama lain (lihat 13.1.2). Jika tidak, kembalikan salah .

Menarik adalah langkah 11. Ya, string diperlakukan sebagai tipe nilai. Tapi ini tidak menjelaskan mengapa String baru ("a")! == "a" . Apakah kita memiliki browser yang tidak sesuai dengan ECMA-262?

Tidak secepat itu!

Mari kita periksa jenis operan. Cobalah sendiri dengan membungkusnya dalam typeof () . Saya menemukan bahwa String baru ("a") adalah objek, dan langkah 1 digunakan: return false jika tipenya berbeda.

Jika Anda bertanya-tanya mengapa String baru ("a") tidak mengembalikan string, bagaimana dengan latihan membaca spesifikasi? Selamat bersenang-senang!


Aidiakapi menulis ini dalam komentar di bawah ini:

Dari spesifikasinya

11.2.2 Operator baru :

Jika Tipe (konstruktor) bukan Objek, lempar pengecualian TypeError.

Dengan kata lain, jika String tidak akan menjadi tipe Object, itu tidak dapat digunakan dengan operator baru.

baru selalu mengembalikan Obyek, bahkan untuk konstruktor String juga. Dan sayangnya! Semantik nilai untuk string (lihat langkah 11) hilang.

Dan ini akhirnya berarti: String baru ("a")! == "a" .

nekat
sumber
Hasil Jenis (x) dinyatakan sama dengan jenis?
Dfr
@ jelas saya tidak benar-benar memahami kecemasan tentang perilaku dengan new String('x'), karena saya belum pernah melihat kode di alam liar yang menggunakan objek pembungkus primitif, dan saya tidak berpikir ada banyak alasan bagus untuk, terutama hari ini. Pernahkah Anda menemukan kode yang melakukannya?
Andy
@Andy masalahnya adalah kode jahat pihak ketiga atau hanya ceroboh, maka Anda tidak dapat berasumsi bahwa tidak ada yang menggunakan new String().
nalply
Jika ceroboh, === adalah bagaimana Anda akan mengetahuinya. Jika itu berbahaya, saya pikir new String()mungkin adalah kekhawatiran Anda yang paling sedikit. Saya memahami keprihatinan dalam teori, tetapi sekali lagi, apakah Anda memiliki contoh dunia nyata? Bagi saya itu seperti kecemasan lama bahwa seseorang dapat menetapkan undefinednilai lain.
Andy
Saya tidak tahu dari mana Anda mendapatkan ini, tetapi algoritma perbandingan Anda salah pada langkah 2. Bagian "7.2.15 Perbandingan Kesetaraan Yang Ketat" pertama-tama memeriksa apakah jenisnya sama, jika ya apakah mereka Angka. Jika tidak, maka bagian "7.2.12 SameValueNonNumber (x, y)" digunakan.
Rusty Core
101

Dalam PHP dan JavaScript, ini adalah operator kesetaraan yang ketat. Yang berarti, itu akan membandingkan jenis dan nilai.

Shiki
sumber
10
@ David: benar. Itu sebabnya jawaban ini tidak akurat (atau bahkan salah)
Philippe Leybaert
7
@ David var a = {}, b = {}; a == bmengembalikan false.
nyuszika7h
6
Ya: Dua objek berbeda dengan jenis dan nilai yang sama dengan false, yaitu, jawaban ini salah. Mengapa ada 50 upvotes?
alexis
4
Saya menyadari ini sudah tua, tetapi untuk menjelaskan mengapa jawaban ini masih "benar" adalah karena dalam contoh var a = {}, b = {};Sementara keduanya adan bmemang keduanya objek, tetapi mereka tidak memiliki nilai yang sama , secara teknis. Mereka adalah contoh yang berbeda . Perhatikan bahwa membandingkan instance berfungsi berbeda dari membandingkan primitif. Yang mungkin menambah kebingungan ini. Anda akan melihat perilaku perbandingan yang serupa jika Anda menggunakan versi tipe data primitif contoh. Misalnya new String('asdf')atau new Number(5). Mis: new Number(5) == new Number(5)salah, meskipun mereka memiliki nilai yang sama.
Norman Breau
1
Kita semua lupa bahwa referensi ke objek sebenarnya adalah Tipe Nilai, karena itu adalah penunjuk ke slot memori. Perbandingan objek tidak membandingkan "nilai objek" tetapi apakah kedua pointer adalah sama yang berarti mereka mereferensikan slot memori yang sama. Itu adalah perbedaan yang sangat halus dalam membandingkan Jenis, karena operator "===" benar-benar perlu mengatakan "jika jenis, nilai, dan referensi ke objek dalam memori adalah sama".
Stokely
101

Saya menguji ini di Firefox dengan Firebug menggunakan kode seperti ini:

console.time("testEquality");
var n = 0;
while(true) {
    n++;
    if(n==100000) 
        break;
}
console.timeEnd("testEquality");

dan

console.time("testTypeEquality");
var n = 0;
while(true) {
    n++;
    if(n===100000) 
        break;
}
console.timeEnd("testTypeEquality");

Hasil saya (masing-masing diuji lima kali dan rata-rata):

==: 115.2
===: 114.4

Jadi saya akan mengatakan bahwa perbedaan sangat kecil (ini lebih dari 100.000 iterasi, ingat) diabaikan. Kinerja bukan alasan untuk melakukannya ===. Ketik keamanan (well, seaman Anda akan mendapatkan JavaScript), dan kualitas kode.

Simon Scarfe
sumber
3
Lebih dari mengetik keamanan yang Anda inginkan kebenaran logis - kadang-kadang Anda ingin hal-hal menjadi jujur ​​ketika ==tidak setuju.
rpjohnst
4
Sekarang, bagaimana perbandingan ini ketika ada koersi tipe aktual untuk ==operator? Ingat, saat itulah ada peningkatan kinerja.
Hubert OG
2
Perbedaan utama ketika diuji dengan benar untuk alasan yang disebutkan di atas lebih cepat untuk hanya memeriksa ketimpangan jenis. jsfiddle.net/4jhuxkb2
Doug Morrow
Anda mengukur kinerja seperti ini dalam operasi / detik, bukan tes tunggal di satu browser (satu dengan sekitar 5% pangsa pasar) menggunakan console.time () saat menggunakan tes yang tidak mengambil tipe paksaan (seluruh alasan lebih lambat) ke akun. Ini adalah ujian yang sama sekali tidak berarti. Anda benar bahwa kinerja bukan alasan untuk menggunakan ===lebih dari ==tetapi Anda salah bahwa kinerja mereka pada dasarnya sama dan bahwa Anda akan berpikir tes ini membuktikan bahwa, dan banyak orang lain setuju, benar-benar tidak masuk akal bagi saya.
Stephen M Irving
97

Dalam JavaScript artinya nilai dan jenis yang sama.

Sebagai contoh,

4 == "4" // will return true

tapi

4 === "4" // will return false 
Dimitar
sumber
87

The === operator disebut operator perbandingan yang ketat, itu tidak berbeda dari == operator.

Mari kita ambil 2 vars a dan b.

Untuk "a == b" untuk mengevaluasi ke true a dan b perlu nilai yang sama .

Dalam kasus "a === b" a dan b harus memiliki nilai yang sama dan juga jenis yang sama untuk dievaluasi menjadi true.

Ambil contoh berikut

var a = 1;
var b = "1";

if (a == b) //evaluates to true as a and b are both 1
{
    alert("a == b");
}

if (a === b) //evaluates to false as a is not the same type as b
{
    alert("a === b");
}

Singkatnya ; menggunakan operator == dapat mengevaluasi true dalam situasi di mana Anda tidak menginginkannya jadi menggunakan operator === akan lebih aman.

Dalam skenario penggunaan 90% itu tidak masalah yang mana yang Anda gunakan, tetapi berguna untuk mengetahui perbedaannya ketika Anda mendapatkan perilaku yang tidak terduga suatu hari.

Dokter Jones
sumber
82

Mengapa ==begitu tak terduga?

Apa yang Anda dapatkan ketika Anda membandingkan string kosong ""dengan angka nol 0?

true

Yap, itu benar menurut ==string kosong dan angka nol adalah waktu yang sama.

Dan itu tidak berakhir di sini, ini satu lagi:

'0' == false // true

Banyak hal menjadi aneh dengan array.

[1] == true // true
[] == false // true
[[]] == false // true
[0] == false // true

Kemudian aneh dengan string

[1,2,3] == '1,2,3' // true - REALLY?!
'\r\n\t' == 0 // true - Come on!

Itu semakin buruk:

Kapan sama tidak sama?

let A = ''  // empty string
let B = 0   // zero
let C = '0' // zero string

A == B // true - ok... 
B == C // true - so far so good...
A == C // **FALSE** - Plot twist!

Izinkan saya mengatakan itu lagi:

(A == B) && (B == C) // true
(A == C) // **FALSE**

Dan ini hanya hal-hal gila yang Anda dapatkan dengan primitif.

Ini benar-benar tingkat gila saat Anda gunakan ==dengan benda.

Pada titik ini Anda mungkin bertanya-tanya ...

Mengapa ini terjadi?

Yah itu karena tidak seperti "triple sama dengan" ( ===) yang hanya memeriksa apakah dua nilai sama.

==melakukan banyak hal lainnya .

Ini memiliki penanganan khusus untuk fungsi, penanganan khusus untuk nulls, tidak terdefinisi, string, apa saja.

Agak aneh.

Bahkan, jika Anda mencoba untuk menulis fungsi yang melakukan apa ==yang akan terlihat seperti ini:

function isEqual(x, y) { // if `==` were a function
    if(typeof y === typeof x) return y === x;
    // treat null and undefined the same
    var xIsNothing = (y === undefined) || (y === null);
    var yIsNothing = (x === undefined) || (x === null);

    if(xIsNothing || yIsNothing) return (xIsNothing && yIsNothing);

    if(typeof y === "function" || typeof x === "function") {
        // if either value is a string 
        // convert the function into a string and compare
        if(typeof x === "string") {
            return x === y.toString();
        } else if(typeof y === "string") {
            return x.toString() === y;
        } 
        return false;
    }

    if(typeof x === "object") x = toPrimitive(x);
    if(typeof y === "object") y = toPrimitive(y);
    if(typeof y === typeof x) return y === x;

    // convert x and y into numbers if they are not already use the "+" trick
    if(typeof x !== "number") x = +x;
    if(typeof y !== "number") y = +y;
    // actually the real `==` is even more complicated than this, especially in ES6
    return x === y;
}

function toPrimitive(obj) {
    var value = obj.valueOf();
    if(obj !== value) return value;
    return obj.toString();
}

Jadi apa artinya ini?

Artinya ==rumit.

Karena rumit, sulit untuk mengetahui apa yang akan terjadi ketika Anda menggunakannya.

Yang berarti Anda bisa berakhir dengan bug.

Jadi moral dari cerita ini adalah ...

Buat hidup Anda lebih mudah.

Gunakan ===sebagai ganti ==.

Tamat.

Luis Perez
sumber
Anda looseEqualsalah. Function == Function.toString()itu benar, tetapi looseEqual(Function, Function.toString())salah. Tidak yakin mengapa Anda memfilter fungsi di awal.
Oriol
@Oriol Anda benar, saya memperbarui kode untuk menjelaskan hal itu, FYI berdasarkan tes saya itu tidak cukup untuk menghapus filter untuk "fungsi", sebagai gantinya "fungsi" harus ditangani secara berbeda sama sekali.
Luis Perez
Sadarilah spec tidak memperlakukan fungsi secara berbeda, mereka hanya objek. Masalahnya tampaknya Anda mengandalkan typeof x === "object"untuk memeriksa apakah itu objek, tetapi `typeof hanya berfungsi untuk primitif non-nol. Anda mungkin tertarik pada daftar cara yang tepat untuk memeriksa apakah suatu nilai adalah objek
Oriol
Saya mencoba mengobati fungsi dan objek yang sama tetapi ternyata hasilnya salah. Sebagai contoh jika fungsi diperlakukan seperti objek kemudian membandingkan suatu fungsi dengan objek yang mengimplementasikan fungsi valueOf () atau toString () yang cocok dengan fungsi akan lewat tetapi pada kenyataannya tidak. Contoh: (function blah() { console.log("test"); }) != {valueOf:function(){return "function blah() { console.log(\"test\"); }";}}- lihat JS Fiddle ini yang menjalankan semua tes: jsfiddle.net/luisperezphd/7k6gcn6g (ada 1.225 permutasi pengujian)
Luis Perez
1
Anda benar, pengamatan hebat, ini menekankan poin utama yang ==melakukan banyak hal sehingga sangat sulit untuk mengantisipasi hasil sementara ===jauh lebih mudah dan dapat diprediksi yang merupakan salah satu alasan utama ===adalah pilihan yang direkomendasikan. (Saya akan menambahkan catatan pada jawaban yang menyebutkan poin Anda)
Luis Perez
81

===memeriksa sisi yang sama dalam jenis dan nilai yang sama .


Contoh:

'1' === 1 // will return "false" because `string` is not a `number`

Contoh umum:

0 == ''  // will be "true", but it's very common to want this check to be "false"

Contoh umum lainnya:

null == undefined // returns "true", but in most cases a distinction is necessary

Banyak kali sebuah untyped cek akan berguna karena Anda tidak peduli jika nilai baik undefined, null, 0 atau""

vsync
sumber
7
juga,'string' !== 'number'
Homer
72

Diagram alir eksekusi Javascript untuk kesetaraan / perbandingan '==='

Kesetaraan yang ketat Javascript

Diagram alir eksekusi Javascript untuk persamaan / perbandingan tidak ketat '=='

Javascript bukan persamaan

Samar Panda
sumber
Saya tidak mengerti mengapa stringpanah menunjuk ke kotak abu-abu besar, apakah itu seharusnya berarti pengganggu sedang melemparkan string ke nomor?
vsync
@vsync Ini menunjuk ke opsi string dalam kotak abu-abu yaitu string -> # || NaN. Javascript bukan bahasa tipe-skrip yaitu pada dasarnya ia dapat memiliki semua jenis variabel. Jadi, itu menunjuk ke kotak abu-abu itu.
Samar Panda
Saya hanya bertanya apakah itu untuk tujuan casting karena stringseharusnya dibandingkan dengan jenis number, jadi pengganggu melihat apa yang harus dibandingkan dengan string dan melemparkan string yang sesuai?
vsync
1
Kotak abu-abu besar adalah apa yang ToNumberakan kembali ketika diberikan tipe yang berbeda, jadi jika diberikan string, ia hanya akan memilih opsi terakhir (dan mengubahnya menjadi angka). hanya ==menggunakan ToNumberdalam kasus string == numberatau di boolean == anythingatas (dan hanya pada string/ boolean). Ini berarti ==tidak akan pernah mengkonversi undefinedatau nullmeskipun mereka berada di kotak abu-abu. (Untuk kombinasi salah satu undefinedatau nullkeduanya, ==akan selalu kembali true. Juga, apakah nilai di sisi kiri atau kanan tidak masalah, ==(dan ===) akan mengembalikan hasil yang sama.)
user2033427
55

JavaScript === vs == .

0==false   // true
0===false  // false, because they are of a different type
1=="1"     // true, auto type coercion
1==="1"    // false, because they are of a different type
Anik Islam Abhi
sumber
54

Ini berarti kesetaraan tanpa paksaan tipe paksaan berarti JavaScript tidak secara otomatis mengkonversi tipe data lain ke tipe data string

0==false   // true,although they are different types

0===false  // false,as they are different types

2=='2'    //true,different types,one is string and another is integer but 
            javaScript convert 2 to string by using == operator 

2==='2'  //false because by using === operator ,javaScript do not convert 
           integer to string 

2===2   //true because both have same value and same types 
Pop Catalin
sumber
48

Dalam skrip tipikal tidak akan ada perbedaan kinerja. Yang lebih penting mungkin fakta bahwa ribuan "===" adalah 1 KB lebih berat dari seribu "==" :) JavaScript profiler dapat memberi tahu Anda jika ada perbedaan kinerja dalam kasus Anda.

Tetapi secara pribadi saya akan melakukan apa yang disarankan JSLint. Rekomendasi ini ada bukan karena masalah kinerja, tetapi karena tipe paksaan berarti ('\t\r\n' == 0)benar.

Konstantin
sumber
4
Tidak selalu benar. Dengan kompresi gzip, perbedaannya akan hampir dapat diabaikan.
Daniel X Moore
1
Setuju, tetapi ribuan "===" juga berarti 10 ribu baris kode sehingga 1kb lebih atau kurang ...;)
Jonny
Jika Anda khawatir tentang ukuran kemudian hanya menukar semua == Anda dengan ===, lalu gunakan regexp yang dibungkus dengan
46

Operator perbandingan yang sama == membingungkan dan harus dihindari.

Jika Anda HARUS hidup dengannya, maka ingatlah 3 hal berikut:

  1. Ini bukan transitif: (a == b) dan (b == c) tidak mengarah ke (a == c)
  2. Ini saling eksklusif untuk negasinya: (a == b) dan (a! = B) selalu memiliki nilai Boolean yang berlawanan, dengan semua a dan b.
  3. Jika ragu, pelajari dengan hati tabel kebenaran berikut:

MEJA KEBENARAN OPERATOR YANG SAMA DI JAVASCRIPT

  • Setiap baris dalam tabel adalah satu set 3 nilai yang sama "sama", yang berarti bahwa setiap 2 nilai di antara mereka sama dengan menggunakan tanda == sama *

** STRANGE: perhatikan bahwa dua nilai pada kolom pertama tidak sama dalam arti itu. **

''       == 0 == false   // Any two values among these 3 ones are equal with the == operator
'0'      == 0 == false   // Also a set of 3 equal values, note that only 0 and false are repeated
'\t'     == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\r'     == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\n'     == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\t\r\n' == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

null == undefined  // These two "default" values are not-equal to any of the listed values above
NaN                // NaN is not equal to any thing, even to itself.
CuongHuyTo
sumber
39

Tidak mungkin ada perbedaan kinerja antara kedua operasi dalam penggunaan Anda. Tidak ada jenis konversi yang harus dilakukan karena kedua parameter sudah tipe yang sama. Kedua operasi akan memiliki perbandingan tipe diikuti oleh perbandingan nilai.

Sean
sumber
38

Iya! Bermasalah.

===operator di javascript memeriksa nilai dan juga mengetik di mana sebagai ==operator hanya memeriksa nilai (melakukan konversi jenis jika diperlukan) .

masukkan deskripsi gambar di sini

Anda dapat dengan mudah mengujinya. Rekatkan kode berikut dalam file HTML dan buka di browser

<script>

function onPageLoad()
{
    var x = "5";
    var y = 5;
    alert(x === 5);
};

</script>

</head>

<body onload='onPageLoad();'>

Anda akan mendapatkan ' false ' dalam peringatan. Sekarang ubah onPageLoad()metode agar alert(x == 5);Anda menjadi kenyataan .

Aniket Thakur
sumber
33

=== Operator memeriksa nilai-nilai serta jenis variabel untuk kesetaraan.

== Operator hanya memeriksa nilai variabel untuk kesetaraan.

Niraj Choubey
sumber
32

Ini tes pemeriksaan yang ketat.

Ini adalah hal yang baik terutama jika Anda memeriksa antara 0 dan false dan null.

Misalnya, jika Anda memiliki:

$a = 0;

Kemudian:

$a==0; 
$a==NULL;
$a==false;

Semua mengembalikan true dan Anda mungkin tidak menginginkan ini. Misalkan Anda memiliki fungsi yang dapat mengembalikan indeks ke-0 array atau false pada kegagalan. Jika Anda mengecek "==" salah, Anda bisa mendapatkan hasil yang membingungkan.

Jadi dengan hal yang sama seperti di atas, tetapi tes yang ketat:

$a = 0;

$a===0; // returns true
$a===NULL; // returns false
$a===false; // returns false
Daniel
sumber
3
Dalam JavaScript, ini sepenuhnya salah dan tidak lengkap salah. 0 != null. -1
Ry-
31

JSLint terkadang memberi Anda alasan tidak realistis untuk memodifikasi barang. ===memiliki kinerja yang persis sama dengan== olah jenisnya sudah sama.

Itu lebih cepat hanya ketika jenis tidak sama, dalam hal ini tidak mencoba untuk mengkonversi jenis tetapi langsung mengembalikan yang salah.

Jadi, IMHO, JSLint mungkin digunakan untuk menulis kode baru, tetapi optimisasi berlebihan yang tidak berguna harus dihindari di semua biaya.

Artinya, tidak ada alasan untuk berubah ==ke ===dalam cek seperti if (a == 'test')ketika Anda mengetahuinya karena fakta bahwa hanya bisa menjadi String.

Memodifikasi banyak kode dengan cara itu menghabiskan waktu pengembang dan pengulas dan tidak menghasilkan apa-apa.

abu
sumber
30

Secara sederhana

==berarti perbandingan antara operan dengan type conversion

&

===berarti perbandingan antara operan tanpa type conversion

Konversi tipe dalam javaScript berarti javaScript secara otomatis mengkonversi tipe data lain menjadi tipe data string.

Sebagai contoh:

123=='123'   //will return true, because JS convert integer 123 to string '123'
             //as we used '==' operator 

123==='123' //will return false, because JS do not convert integer 123 to string 
            //'123' as we used '===' operator 
Amit
sumber
26

Contoh sederhana adalah

2 == '2'  -> true, values are SAME because of type conversion.

2 === '2'  -> false, values are NOT SAME because of no type conversion.
Vara
sumber
25

2 jawaban teratas yang disebutkan == berarti persamaan dan === berarti identitas. Sayangnya, pernyataan ini salah.

Jika kedua operan == adalah objek, maka mereka dibandingkan untuk melihat apakah keduanya adalah objek yang sama. Jika kedua operan menunjuk ke objek yang sama, maka operator yang sama mengembalikan true. Kalau tidak, keduanya tidak sama.

var a = [1, 2, 3];  
var b = [1, 2, 3];  
console.log(a == b)  // false  
console.log(a === b) // false  

Dalam kode di atas, == dan === salah, karena a dan b bukan objek yang sama.

Itu mengatakan: jika kedua operan == adalah objek, == berperilaku sama dengan ===, yang juga berarti identitas. Perbedaan mendasar dari kedua operator ini adalah tentang konversi tipe. == memiliki konversi sebelum memeriksa kesetaraan, tetapi === tidak.

Harry He
sumber
24

Sebagai aturan praktis, saya biasanya akan menggunakan ===bukannya ==(dan !==bukannya!= ).

Alasan dijelaskan dalam jawaban di atas dan juga Douglas Crockford cukup jelas tentang hal itu ( JavaScript: The Good Parts ).

Namun ada satu pengecualian tunggal : == nulladalah cara yang efisien untuk memeriksa 'apakah nol atau tidak terdefinisi':

if( value == null ){
    // value is either null or undefined
}

Misalnya jQuery 1.9.1 menggunakan pola ini 43 kali, dan pemeriksa sintaks JSHint bahkan menyediakaneqnull opsi untuk alasan ini.

Dari panduan gaya jQuery :

Pemeriksaan kesetaraan yang ketat (===) harus digunakan untuk ==. Satu-satunya pengecualian adalah ketika memeriksa tidak terdefinisi dan null dengan nol.

// Check for both undefined and null values, for some important reason. 
undefOrNull == null;
mar10
sumber
22

Masalahnya adalah Anda mungkin dengan mudah mendapat masalah karena JavaScript memiliki banyak konversi tersirat yang berarti ...

var x = 0;
var isTrue = x == null;
var isFalse = x === null;

Yang segera menjadi masalah. Sampel terbaik mengapa konversi implisit adalah "jahat" dapat diambil dari kode ini di MFC / C ++ yang sebenarnya akan dikompilasi karena konversi implisit dari CString ke HANDLE yang merupakan tipe pointer typedef ...

CString x;
delete x;

Yang jelas selama runtime melakukan hal-hal yang sangat tidak jelas ...

Google untuk konversi tersirat dalam C ++ dan STL untuk mendapatkan beberapa argumen yang menentangnya ...

Thomas Hansen
sumber
2
0 == nullitu salah.
Garrett
21

Perbandingan kesetaraan:

Operator ==

Mengembalikan nilai true, ketika kedua operan sama. Operan dikonversi ke jenis yang sama sebelum dibandingkan.

>>> 1 == 1
true
>>> 1 == 2
false
>>> 1 == '1'
true

Perbandingan kesetaraan dan jenis:

Operator ===

Mengembalikan nilai true jika kedua operan sama dan dari jenis yang sama. Biasanya lebih baik dan lebih aman jika Anda membandingkan cara ini, karena tidak ada konversi tipe di belakang layar.

>>> 1 === '1'
false
>>> 1 === 1
true
pengguna2601995
sumber
20

Berikut ini adalah tabel perbandingan yang berguna yang menunjukkan konversi yang terjadi dan perbedaan antara ==dan ===.

Sebagai kesimpulan menyatakan:

"Gunakan tiga sama dengan kecuali Anda sepenuhnya memahami konversi yang terjadi untuk dua-sama."

http://dorey.github.io/JavaScript-Equality-Table/

Christian Hagelid
sumber
20

null dan undefined adalah ketiadaan, yaitu,

var a;
var b = null;

Di sini adan btidak memiliki nilai. Sedangkan, 0, false dan '' adalah semua nilai. Satu hal yang umum di antara semua ini adalah bahwa semua itu adalah nilai-nilai palsu, yang berarti semuanya memuaskan kondisi palsu.

Jadi, 0, false, dan '' bersama-sama membentuk sub-grup. Dan di sisi lain, null & undefined membentuk sub-grup kedua. Periksa perbandingan pada gambar di bawah ini. null dan undefined akan sama. Tiga lainnya akan sama satu sama lain. Tapi, mereka semua diperlakukan sebagai kondisi palsu dalam JavaScript.

Masukkan deskripsi gambar di sini

Ini sama dengan objek apa pun (seperti {}, array, dll.), String tidak kosong & Boolean true adalah semua kondisi yang benar. Tapi, mereka semua tidak setara.

vivek_nk
sumber