Rumah >hujung hadapan web >tutorial js >DON ' T Takut Kembar Evil - Sitepoint
dan ==
sebagai "kembar jahat" yang harus dielakkan. Walau bagaimanapun, apabila anda memahaminya, pengendali ini tidak begitu buruk dan sebenarnya boleh berguna. Artikel ini akan meneroka !=
dan ==
, menerangkan bagaimana mereka bekerja, dan membantu anda memahami mereka dengan lebih baik. !=
mata utama
==
!=
===
dan !==
apabila anda perlu membuang atau membandingkan nilai -nilai yang jenisnya boleh berubah secara dinamik. ==
!=
==
!=
==
!=
==
!=
dan pengendali ==
!=
bahasa JavaScript mengandungi dua set pengendali kesamaan:
, dan ===
dan !==
. Memahami mengapa terdapat dua set pengendali kesamaan dan di mana situasi untuk menggunakan pengendali yang menjadi sumber kekeliruan bagi ramai orang. Pengendali ==
dan !=
tidak sukar difahami. Apabila kedua -dua jenis operan adalah sama dan nilai -nilai adalah sama, ===
pulangan !==
dan ===
pulangan true
. Walau bagaimanapun, apabila nilai atau jenis berbeza, !==
pulangan false
, ===
pulangan false
. Pengendali !==
dan true
berkelakuan sama apabila kedua -dua jenis operan adalah sama. Walau bagaimanapun, apabila jenisnya berbeza, JavaScript membuang satu operan ==
ke jenis lain untuk menjadikan operan serasi sebelum perbandingan. Hasilnya sering mengelirukan, seperti berikut: !=
Kerana hanya terdapat dua nilai boolean yang mungkin, anda mungkin berfikir bahawa salah satu ungkapan harus dikira sebagai
<code class="language-javascript">"this_is_true" == false // false "this_is_true" == true // false</code>. Kekeliruan tambahan berlaku apabila anda mengandaikan bahawa hubungan lulus (jika A adalah sama dengan B dan B adalah sama dengan C) harus dikenakan:
<code class="language-javascript">"this_is_true" == false // false "this_is_true" == true // false</code>
Contoh ini menunjukkan bahawa ==
tidak mempunyai transitivenes. Jika rentetan kosong sama dengan nombor 0, dan jika nombor 0 adalah sama dengan rentetan yang terdiri daripada aksara 0, rentetan kosong harus sama dengan rentetan yang terdiri daripada 0. Tetapi itu tidak berlaku. Apabila jenis yang tidak serasi ditemui apabila membandingkan operan melalui ==
atau !=
, JavaScript membuang satu jenis ke yang lain untuk menjadikannya setanding. Sebaliknya, apabila menggunakan ===
dan !==
, ia tidak pernah melakukan jenis cast (yang membawa kepada peningkatan sedikit prestasi). Oleh kerana jenis yang berbeza, ===
selalu mengembalikan false
dalam contoh kedua. Memahami peraturan yang mengawal bagaimana JavaScript membuang operan kepada pelbagai jenis supaya kedua -dua jenis operan serasi sebelum menggunakan ==
dan !=
dapat membantu anda menentukan kapan lebih baik menggunakan ==
dan !=
, dan mempunyai keyakinan dalam menggunakan pengendali ini. Dalam bahagian seterusnya, kami akan meneroka peraturan pelakon yang digunakan dengan pengendali ==
dan !=
.
==
dan !=
berfungsi?
dan ==
adalah untuk mengkaji spesifikasi bahasa ECMAScript. Bahagian ini memberi tumpuan kepada ECMAScript 262. Seksyen 11.9 Spesifikasi memperkenalkan pengendali kesamaan. Pengendali !=
dan ==
muncul dalam pengeluaran sintaks !=
dan EqualityExpression
. (Tidak seperti generasi pertama, generasi kedua mengelakkan pengendali EqualityExpressionNoIn
.) Mari kita periksa generasi in
yang ditunjukkan di bawah. EqualityExpression
<code class="language-javascript">'' == 0 // true 0 == '0' // true '' == '0' // false</code>Menurut generasi ini, ungkapan yang sama adalah sama ada ungkapan relasi, atau ungkapan yang sama yang sama dengan ekspresi hubungan, atau ungkapan yang sama yang tidak sama dengan ekspresi hubungan, dan lain -lain. (Saya terlepas pandang
dan ==
, yang tidak berkaitan dengan artikel ini.) Seksyen 11.9.1 memberikan maklumat berikut mengenai cara !=
berfungsi: ===
!==
==
Formula Pengeluaran
menjadi hasil pengiraan
EqualityExpression : EqualityExpression == RelationalExpression
biarkan.
- .
lref
biarkanEqualityExpression
be- .
lval
biarkanGetValue(lref)
menjadi hasil pengiraan- .
rref
biarkanRelationalExpression
berval
Mengembalikan hasil melakukan perbandingan kesamaan abstrakGetValue(rref)
. (Lihat 11.9.3.)- berfungsi:
rval == lval
Seksyen 11.9.2 Menyediakan maklumat yang sama tentang cara
Formula Pengeluaran !=
dikira seperti berikut:
lref
menjadi hasil pengiraan EqualityExpression
. lval
be GetValue(lref)
. rref
menjadi hasil pengiraan RelationalExpression
. rval
be GetValue(rref)
. r
menjadi hasil daripada melakukan perbandingan kesamaan abstrak rval != lval
. (Lihat 11.9.3.) r
, kembali true
. Jika tidak, kembali false
. true
dan lref
adalah rujukan di sebelah kiri dan kanan rref
dan ==
pengendali. Setiap rujukan dihantar kepada fungsi dalaman !=
untuk mengembalikan nilai yang sepadan. Inti bagaimana kerja GetValue()
dan ==
ditentukan oleh algoritma perbandingan kesamaan abstrak, yang diberikan dalam Seksyen 11.9.3: !=
Bandingkan, di mana
x == y
danx
adalah nilai, menghasilkany
atautrue
. Perbandingan ini dijalankan seperti berikut:false
- jika
Type(x)
sama denganType(y)
, maka
- jika
Type(x)
adalahUndefined
, kembalitrue
.- jika
Type(x)
adalahNull
, kembalitrue
.- jika
Type(x)
adalahNumber
, maka
- jika
x
adalahNaN
, kembalifalse
.- jika
y
adalahNaN
, kembalifalse
.- Jika
x
dany
adalah nilai berangka yang sama, kembalitrue
.- jika
x
adalah 0 dany
adalah -0, kembalitrue
.- jika
x
adalah -0 dany
adalah 0, makatrue
akan dikembalikan.- kembali
false
.- jika
Type(x)
adalahString
, jikax
dany
betul -betul urutan watak yang sama (panjang yang sama dan aksara yang sama dalam kedudukan yang sama), makatrue
dikembalikan. Jika tidak, kembalifalse
.- jika
Type(x)
adalahBoolean
, maka jikax
dany
kedua -duanyatrue
atau kedua -duanyafalse
, kemudian kembalitrue
. Jika tidak, kembalifalse
.- Jika
x
dany
merujuk kepada objek yang sama, kembalitrue
. Jika tidak, kembalifalse
.- jika
x
adalahnull
dany
adalahundefined
, kemudian kembalitrue
.- jika
x
adalahundefined
dany
adalahnull
, kemudian kembalitrue
.- jika
Type(x)
adalahNumber
danType(y)
adalahString
, hasil perbandinganx == ToNumber(y)
dikembalikan.- jika
Type(x)
adalahString
danType(y)
adalahNumber
, hasil perbandinganToNumber(x) == y
dikembalikan.- Jika
Type(x)
adalahBoolean
, hasil perbandinganToNumber(x) == y
dikembalikan.- Jika
Type(y)
adalahBoolean
, hasil perbandinganx == ToNumber(y)
dikembalikan.- jika
Type(x)
adalahString
atauNumber
danType(y)
adalahObject
, hasil perbandinganx == ToPrimitive(y)
dikembalikan.- jika
Type(x)
adalahObject
danType(y)
adalahString
atauNumber
, hasil perbandinganToPrimitive(x) == y
dikembalikan.- kembali
false
.
Langkah 1 Jenis pengendali adalah sama apabila dilaksanakan dalam algoritma ini. Ia menunjukkan bahawa
Memahami Kembar Evil
Contoh kedua saya (berdasarkan penjelasan makna kehidupan dalam "Panduan Galaxy Wandering") membandingkan objek dengan nombor dengan Langkah -langkah berikut menunjukkan bagaimana JavaScript menggunakan algoritma perbandingan kesamaan abstrak untuk mendapatkan Untuk contoh terakhir saya, mari kita ketahui mengapa urutan berikut tidak menunjukkan transitiveness, di mana perbandingan ketiga akan kembali Langkah -langkah berikut menunjukkan bagaimana JavaScript menggunakan algoritma perbandingan kesamaan abstrak untuk mendapatkan Langkah -langkah berikut menunjukkan bagaimana JavaScript menggunakan algoritma perbandingan kesamaan abstrak untuk mendapatkan Akhirnya, JavaScript melakukan langkah 1.D dalam algoritma perbandingan kesamaan abstrak untuk mendapatkan Kesimpulan Anda mungkin tertanya -tanya mengapa anda perlu bersusah payah menggunakan Contoh -contoh ini menunjukkan bahawa
Apakah perbezaan antara adalah pengendali perbandingan. Walau bagaimanapun, mereka berbeza dengan cara mereka membandingkan nilai. Pengendali dalam JavaScript, kerana ia memberikan perbandingan yang lebih ketat, yang bermaksud ia tidak melakukan jenis cast dan cek untuk nilai dan jenis. Ini dapat membantu mengelakkan hasil yang tidak dijangka apabila membandingkan pelbagai jenis nilai. Sebagai contoh, apabila menggunakan Dalam JavaScript, objek dibandingkan dengan rujukan, bukan dengan nilai. Ini bermakna walaupun dua objek mempunyai sifat dan nilai yang sama, mereka tidak dianggap sama kerana mereka merujuk kepada objek yang berbeza dalam ingatan. Satu -satunya kes di mana objek dianggap sama adalah bahawa mereka merujuk kepada objek yang sama. Dalam JavaScript, tatasusunan adalah objek, berbanding dengan rujukan, bukan dengan nilai. Ini bermakna walaupun dua tatasusunan mengandungi unsur yang sama dalam urutan yang sama, mereka tidak dianggap sama kerana mereka merujuk kepada objek yang berbeza dalam ingatan. Untuk membandingkan dua tatasusunan dengan kandungan mereka, anda perlu membandingkan setiap elemen secara berasingan. dalam JavaScript, Di JavaScript, pengendali perbandingan mempunyai tahap keutamaan yang sama. Mereka dikira dari kiri ke kanan. Walau bagaimanapun, adalah penting untuk diperhatikan bahawa mereka mempunyai keutamaan yang lebih rendah daripada pengendali aritmetik dan bitwise, tetapi lebih tinggi daripada pengendali logik. Ya, anda boleh menggunakan pengendali perbandingan dengan rentetan dalam JavaScript. JavaScript menggunakan perintah leksikal (kamus) apabila membandingkan rentetan. Walau bagaimanapun, adalah penting untuk diperhatikan bahawa huruf modal dianggap "kecil" daripada huruf kecil kerana mereka mempunyai nilai ASCII yang lebih kecil. undefined
sama dengan undefined
, dan null
sama dengan null
.Ia juga menunjukkan bahawa tiada sama dengan NaN
(bukan nombor), dua nilai yang sama adalah sama, 0 sama dengan -0, dua rentetan dengan panjang dan urutan yang sama adalah sama, true
sama dengan true
, false
sama dengan false
, dan dua rujukan kepada objek yang sama adalah sama. Langkah 2 dan 3 menunjukkan mengapa null != undefined
kembali false
. JavaScript menganggap nilai -nilai ini sama. Bermula dari langkah 4, algoritma menjadi menarik. Langkah ini memberi tumpuan kepada kesaksamaan antara nilai String
dan operan kedua adalah Number
, operan kedua ditukar kepada String
melalui fungsi dalaman ToNumber()
. Ekspresi Number
bermaksud rekursi; Langkah 5 bersamaan dengan langkah 4, tetapi pengendali pertama mempunyai jenis x == ToNumber(y)
dan mesti ditukar kepada jenis String
. Langkah 6 dan 7 Tukar operand boolean ke jenis Number
dan rekursif. Jika operan lain adalah boolean, ia akan ditukar kepada Number
pada masa akan datang algoritma ini dilaksanakan, yang akan berulang lagi. Dari sudut pandangan prestasi, anda mungkin ingin memastikan kedua -dua operan adalah jenis Boolean untuk mengelakkan dua langkah rekursif. Langkah 9 menunjukkan bahawa jika jenis mana -mana pengendali adalah Number
, operan ditukar kepada nilai asal melalui fungsi dalaman Object
, dan algoritma secara rekursif. Akhirnya, algoritma menganggap bahawa kedua -dua pengendali tidak sama dan pulangan ToPrimitive()
dalam langkah 10. Walaupun terperinci, algoritma perbandingan kesamaan abstrak agak mudah difahami. Walau bagaimanapun, ia merujuk sepasang fungsi dalaman false
dan ToNumber()
, yang kerja dalamannya perlu terdedah untuk memahami sepenuhnya algoritma. Fungsi ToPrimitive()
menukarkan parameternya ke ToNumber()
dan diterangkan dalam Bahagian 9.3. Senarai berikut meringkaskan kemungkinan parameter bukan angka dan nilai pulangan yang setara: Number
Fungsi Undefined
, kembali NaN
. Null
, kembali 0. true
, kembali 1. Jika parameter adalah nilai boolean false
, kembali 0. Number
, parameter input dikembalikan - tiada penukaran. String
, maka seksyen 9.3.1 "Tonumber jenis rentetan" digunakan. Mengembalikan nilai yang sepadan dengan parameter rentetan yang ditunjukkan oleh sintaks. Jika parameter tidak sepadan dengan sintaks yang ditunjukkan, kembali NaN
. Sebagai contoh, parameter "XYZ" menyebabkan pulangan NaN
. Tambahan pula, parameter "29" menghasilkan pulangan 29. Object
, gunakan langkah -langkah berikut:
primValue
be ToPrimitive(输入参数, 提示Number)
. ToNumber(primValue)
. ToPrimitive()
menerima parameter input dan parameter pilihan PreferredType
. Parameter input ditukar kepada jenis bukan objek. Jika objek boleh ditukar kepada pelbagai jenis primitif, ToPrimitive()
gunakan pilihan PreferredType
prompt untuk bias jenis pilihan. Penukaran dijalankan seperti berikut:
Undefined
, parameter input (Undefined
) dikembalikan - tiada penukaran. Null
, parameter input (Null
) dikembalikan - tiada penukaran. Boolean
, kembalikan parameter input - tiada penukaran. Number
, kembalikan parameter input - tiada penukaran. String
, kembalikan parameter input - tiada penukaran. Object
, nilai lalai yang sepadan dengan parameter input dikembalikan. Ambil nilai lalai objek dengan memanggil kaedah [[DefaultValue]]
objek PreferredType
dan lulus prompt [[DefaultValue]]
pilihan. Tingkah laku ==
Bahagian ini memperkenalkan banyak teori. Dalam bahagian seterusnya, kami akan beralih kepada amalan dengan menyediakan pelbagai ungkapan yang melibatkan !=
dan ==
Sekarang kita telah memahami bagaimana !=
dan true
berfungsi mengikut spesifikasi ECMAScript, marilah kita mengambil kesempatan daripada pengetahuan ini dengan meneroka pelbagai ungkapan yang melibatkan pengendali ini. Kami akan berjalan melalui cara menilai ungkapan ini dan mengetahui mengapa mereka false
atau <code class="language-javascript">"this_is_true" == false // false
"this_is_true" == true // false</code>
typeof "this_is_true"
mengembalikan "rentetan", sementara typeof false
atau typeof true
mengembalikan "boolean". Boolean
. Ekspresi ditukar kepada "this_is_true" == ToNumber(false)
dan "this_is_true" == ToNumber(true)
. ToNumber(false)
pulangan 0, ToNumber(true)
pulangan 1, yang memudahkan ungkapan ke "this_is_true" == 0
dan "this_is_true" == 1
masing -masing. Pada masa ini algoritma secara rekursif. String
dan jenis pengendali kanan adalah Number
. Ekspresi ditukar kepada ToNumber("this_is_true") == 0
dan ToNumber("this_is_true") == 1
. ToNumber("this_is_true")
kembali NaN
, yang memudahkan ekspresi ke NaN == 0
dan NaN == 1
masing -masing. Pada masa ini algoritma secara rekursif. NaN
, 0 dan 1 adalah semua Number
. Langkau Langkah 1.A dan 1.B yang tidak berkenaan. Walau bagaimanapun, langkah 1.c.i terpakai kerana operan kiri adalah NaN
. Algoritma kini kembali false
(NaN
tidak sama dengan apa -apa, termasuk dirinya sendiri) sebagai nilai setiap ungkapan asal dan backtracks timbunan untuk keluar dari rekursi sepenuhnya. ==
dan mengembalikan true
: <code class="language-javascript">"this_is_true" == false // false
"this_is_true" == true // false</code>
true
sebagai nilai ungkapan:
Object
dan jenis pengendali kanan adalah Number
. Ekspresi ditukar kepada ToPrimitive(lifeAnswer) == 42
. ToPrimitive()
Panggil lifeAnswer
kaedah dalaman [[DefaultValue]]
, tanpa segera. Menurut Seksyen 8.12.8 spesifikasi ECMAScript 262, [[DefaultValue]]
memanggil kaedah toString()
, yang mengembalikan "42". Ekspresi ditukar kepada "42" == 42
, dan algoritma adalah rekursif. String
dan jenis pengendali kanan adalah Number
. Ekspresi ditukar kepada ToNumber("42") == 42
. ToNumber("42")
mengembalikan 42, dan ungkapan ditukar kepada 42 == 42
. Algoritma ini berulang dan melaksanakan langkah 1.C.III. Kerana angka -angka itu sama, true
dikembalikan dan diperluas secara rekursif. true
bukan false
: <code class="language-javascript">"this_is_true" == false // false
"this_is_true" == true // false</code>
true
sebagai nilai '' == 0
.
ToNumber('') == 0
, yang ditukar kepada 0 == 0
, dan algoritma secara rekursif. (Seksyen 9.3.1 spesifikasi menyatakan bahawa stringnumericliteral ::: [kosong] 's mv [nilai matematik] adalah 0. Dengan kata lain, nilai rentetan kosong adalah 0.) true
(dan memperluaskan rekursi). true
sebagai nilai 0 == '0'
:
0 == ToNumber('0')
, yang ditukar kepada 0 == 0
, dan algoritma secara rekursif. true
(dan memperluaskan rekursi). true
sebagai nilai '' == '0'
. Kerana kedua -dua rentetan mempunyai panjang yang berbeza (0 dan 1), kembali false
. ==
dan !=
. Lagipun, contoh -contoh sebelumnya telah menunjukkan bahawa pengendali ini mungkin lebih perlahan daripada pengendali ===
dan !==
kerana jenis pemutus dan rekursi. Anda mungkin mahu menggunakan ==
dan !=
kerana dalam beberapa kes tidak ada kelebihan. Pertimbangkan contoh berikut: ===
<code class="language-javascript">"this_is_true" == false // false
"this_is_true" == true // false</code>
Pengendali typeof
mengembalikan nilai String
. Kerana nilai String
dibandingkan dengan nilai String
yang lain ("objek"), tiada jenis pemutus berlaku, dan ==
adalah efisien seperti ===
. Mungkin seorang pemula JavaScript yang tidak pernah menemui ===
akan mencari kod tersebut lebih jelas. Begitu juga, coretan kod berikut tidak memerlukan pemutus jenis (jenis kedua -dua operan adalah Number
), jadi !=
adalah efisien seperti !==
: <code class="language-javascript">'' == 0 // true
0 == '0' // true
'' == '0' // false</code>
==
dan !=
sesuai untuk perbandingan yang tidak memerlukan pemutus. Apabila jenis pengendali adalah berbeza, ===
dan !==
adalah pilihan terbaik kerana mereka kembali false
daripada nilai -nilai yang tidak dijangka (mis. Jika jenis pengendali adalah sama, tidak ada sebab untuk tidak menggunakan false == ""
dan true
. Mungkin sudah tiba masanya untuk berhenti takut kepada kembar jahat, dan apabila anda memahami mereka, mereka kurang jahat. ==
!=
dalam JavaScript?
dan ==
===
dalam JavaScript, ==
(juga dikenali sebagai pengendali kesamaan longgar) melakukan jenis pemutus sebelum perbandingan. Ini bermakna jika anda membandingkan dua jenis nilai, JavaScript akan cuba menukar satu jenis ke yang lain sebelum melakukan perbandingan. Sebaliknya, pengendali ===
(dipanggil pengendali kesamaan yang ketat) tidak melakukan pemutus jenis. Ia membandingkan nilai dan jenis pada masa yang sama, yang bermaksud bahawa jika kedua -dua jenis nilai berbeza, JavaScript akan menganggapnya tidak sama rata. ==
===
Kenapa saya harus menggunakan dalam JavaScript?
bukannya ===
==
umumnya disyorkan untuk menggunakan ===
, JavaScript menganggap nombor 0 dan rentetan kosong "" sama, kerana ia menukarkan jenis sebelum perbandingan. Walau bagaimanapun, dengan menggunakan ==
, mereka akan dianggap tidak sama rata kerana mereka mempunyai pelbagai jenis. ==
===
Apakah jenis pelakon dalam JavaScript? Taipkan Cast dalam JavaScript merujuk kepada nilai -nilai yang ditukar secara automatik atau secara tersirat dari satu jenis data ke yang lain. Ini berlaku apabila pengendali digunakan untuk pelbagai jenis operan atau apabila beberapa jenis diperlukan. Sebagai contoh, apabila menggunakan pengendali kesamaan longgar (
Bagaimanakah JavaScript mengendalikan perbandingan objek?
==
dan !=
dalam JavaScript? ==
dan !=
adalah pengendali perbandingan dalam JavaScript. Pengendali ==
memeriksa sama ada nilai kedua -dua pengendali adalah sama, dan melakukan jenis cast jika perlu. Sebaliknya, pengendali !=
memeriksa sama ada nilai kedua -dua operan tidak sama, dan melakukan jenis cast jika perlu.
===
dan !==
dalam JavaScript? ===
dan !==
adalah pengendali perbandingan dalam JavaScript. Pengendali ===
memeriksa sama ada nilai kedua -dua pengendali adalah sama, dengan mengambil kira kedua -dua nilai dan jenis. Sebaliknya, pengendali !==
memeriksa sama ada nilai kedua -dua operan tidak sama, dengan mengambil kira kedua -dua nilai dan jenis. Bagaimana membandingkan dua tatasusunan dalam JavaScript?
Bagaimanakah JavaScript mengendalikan perbandingan antara
null
dan undefined
? null
dan undefined
dianggap longgar sama (==
) kerana kedua -duanya mewakili nilai yang hilang. Walau bagaimanapun, mereka tidak sama sama (===
) kerana mereka mempunyai pelbagai jenis. Apakah urutan keutamaan pengendali perbandingan dalam JavaScript?
Bolehkah saya menggunakan pengendali perbandingan dengan rentetan dalam javascript?
Atas ialah kandungan terperinci DON ' T Takut Kembar Evil - Sitepoint. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!