Seperti yang kita semua tahu, == Dalam JavaScript adalah operasi yang relatif kompleks. Aturan operasinya sangat aneh dan dapat dengan mudah membuat kesalahan, menjadikannya salah satu "fitur terburuk" di JavaScript.
Berdasarkan dengan cermat membaca spesifikasi ecmascript, saya menggambar. Saya pikir setelah Anda memahami gambar ini, Anda akan benar -benar memahami segala sesuatu tentang operasi ==. Pada saat yang sama, saya mencoba membuktikan kepada semua orang melalui artikel ini bahwa == bukanlah hal yang buruk. Mudah dikuasai dan bahkan terlihat masuk akal dan tidak seburuk itu.
Pertama, gambarnya:
== Deskripsi yang tepat dari aturan operasi ada di sini: algoritma perbandingan kesetaraan abstrak. Namun, dengan deskripsi yang rumit, apakah Anda yakin tidak akan merasa pusing setelah membacanya? Bisakah Anda menggunakannya untuk memandu latihan Anda segera?
Itu pasti tidak berhasil. Lagi pula, spesifikasinya adalah untuk pengembang JavaScript Running Environment (dibandingkan dengan pengembang mesin V8), bukan untuk pengguna bahasa. Gambar di atas menerjemahkan spesifikasi ke dalam bentuk yang nyaman untuk dilihat semua orang.
Sebelum memperkenalkan setiap bagian dalam Gambar 1 secara detail, mari kita tinjau pengetahuan tentang jenis di JS:
Ada dua jenis nilai dalam JS: tipe dasar dan tipe objek.
Tipe dasar meliputi: tidak terdefinisi, nol, boolean, angka dan string.
Baik tipe yang tidak terdefinisi dan tipe nol hanya memiliki satu nilai, yaitu tidak terdefinisi dan nol; Jenis Boolean memiliki dua nilai: benar dan salah; Ada banyak nilai dari jenis angka; dan tipe string memiliki nilai yang tak terhitung jumlahnya (secara teoritis).
Semua objek memiliki nilai () dan metode tostring (), yang diwarisi dari objek dan tentu saja dapat ditulis ulang oleh subkelas.
Sekarang pertimbangkan ekspresinya:
x == y
di mana x dan y adalah nilai dari salah satu dari enam jenis.
Ketika jenis x dan y sama, x == y dapat dikonversi menjadi x === Y, dan yang terakhir sangat sederhana (satu -satunya hal yang perlu diperhatikan adalah NAN), jadi di bawah ini kami hanya mempertimbangkan kasus -kasus di mana jenis x dan y berbeda.
1. Memiliki dan tidak ada
Pada Gambar 1, enam jenis nilai JavaScript diwakili oleh persegi panjang dengan latar belakang biru. Pertama mereka dibagi menjadi dua kelompok:
String, angka, boolean dan objek (sesuai dengan kotak persegi panjang besar di sebelah kiri)
Tidak terdefinisi dan nol (sesuai dengan kotak persegi panjang di sebelah kanan)
Apa dasar untuk pengelompokan? Mari kita lihat. Tidak terdefinisi dan nol di sebelah kanan digunakan untuk menunjukkan ketidakpastian, non-atau kosong, sedangkan keempat jenis di sebelah kanan semuanya ditentukan, ada dan tidak kosong. Kita bisa mengatakan ini:
Di sebelah kiri adalah dunia keberadaan, dan di sebelah kanan adalah dunia yang kosong.
Oleh karena itu, masuk akal untuk membandingkan nilai apa pun di kedua dunia dengan false. (mis., Garis horizontal yang menghubungkan dua persegi panjang pada Gambar 1 ditandai salah)
2. Kosong dan kosong
Tidak terdefinisi dan nol di JavaScript adalah tempat lain yang sering menabrak kita. Biasanya dianggap cacat desain, yang tidak akan kita gali. Tetapi saya telah mendengar bahwa penulis Javascript awalnya menganggap ini:
Jika Anda berencana untuk menetapkan variabel ke nilai jenis objek, tetapi belum menetapkan nilai, maka Anda dapat menggunakan null untuk mewakili keadaan saat ini (salah satu bukti adalah bahwa hasil dari tipe null adalah 'objek'); Sebaliknya, jika Anda berencana untuk menetapkan variabel ke nilai jenis asli, tetapi belum menetapkan nilai, maka Anda dapat menggunakan tidak ditentukan untuk mewakili keadaan saat ini.
Terlepas dari apakah rumor ini kredibel atau tidak, masuk akal bahwa hasil perbandingan antara keduanya benar. (mis. Benar ditandai pada garis vertikal di sebelah kanan pada Gambar 1)
Sebelum pindah ke langkah berikutnya, mari kita bicara tentang dua simbol pada Gambar 1: Capital Letters n dan P. Kedua simbol ini tidak berarti positif dan negatif di bagian PN. Alih-alih:
N mewakili operasi tonumber, yang berarti mengubah operan menjadi angka. Ini adalah operasi abstrak dalam spesifikasi ES, tetapi kita dapat menggunakan fungsi angka () dalam JS untuk menggantinya secara setara.
P mewakili operasi toprimitive, yaitu, mengonversi operan ke nilai jenis asli. Ini juga merupakan operasi abstrak dalam spesifikasi ES, dan juga dapat diterjemahkan ke dalam kode JS yang setara. Tapi itu sedikit lebih rumit. Sederhananya, untuk objek obj:
TopRimitive (OBJ) setara dengan: Pertama Hitung OBJ.VALUEOF (), jika hasilnya adalah nilai aslinya, hasil ini dikembalikan; Jika tidak, obj.tostring () dihitung, dan jika hasilnya adalah nilai aslinya, hasil ini dikembalikan; Kalau tidak, pengecualian dilemparkan.
CATATAN: Ada pengecualian di sini, yaitu objek tanggal jenis, yang pertama -tama akan memanggil metode tostring ().
Pada Gambar 1, garis yang ditandai N atau P menunjukkan bahwa ketika dua jenis data dihubungkan untuk melakukan operasi ==, operan di samping yang ditandai N atau P harus terlebih dahulu melakukan transformasi tonumber atau toprimitive.
3. Benar dan Salah
Seperti dapat dilihat dari Gambar 1, ketika nilai boolean dibandingkan dengan jenis nilai lainnya, nilai boolean dikonversi menjadi angka. Secara khusus
Benar -> 1
Salah -> 0
Ini tidak membutuhkan terlalu banyak pelecehan verbal sama sekali. Pikirkan tentang hal ini, di C, tidak ada tipe boolean sama sekali. Integers 1 dan 0 biasanya digunakan untuk mewakili logika yang benar atau salah.
Iv. Urutan karakter
Pada Gambar 1, kami membagi string dan angka menjadi grup. Mengapa? Di antara enam jenis, string dan angka adalah urutan karakter (setidaknya secara harfiah). String adalah urutan dari semua karakter hukum, sedangkan angka dapat dianggap sebagai urutan karakter yang memenuhi kondisi tertentu. Oleh karena itu, angka dapat dianggap sebagai subset dari string.
Menurut Gambar 1, saat melakukan operasi string dan angka ==, Anda perlu menggunakan operasi tonumber untuk mengubah string menjadi angka. Dengan asumsi x adalah string dan y adalah angka, lalu:
x == y -> angka (x) == y
Jadi apa aturan untuk mengubah string menjadi angka? Spesifikasi dijelaskan dengan cara yang sangat rumit, tetapi secara umum, itu adalah untuk menghapus kutipan di kedua sisi string dan melihat apakah itu dapat membentuk bilangan hukum. Jika demikian, hasil konversi adalah angka ini; Kalau tidak, hasilnya adalah Nan. Misalnya:
Angka ('123') // Hasil 123
Angka ('1.2e3') // hasil 1200
Angka ('123abc') // hasil nan
Tentu saja, ada pengecualian, seperti hasil mengubah string kosong menjadi angka adalah 0. sekarang
Number ('') // Hasil 0
V. Sederhana dan Kompleks
Jenis primitif adalah tipe sederhana, mereka langsung dan mudah dimengerti. Namun, kerugiannya adalah bahwa kemampuan ekspresi terbatas dan sulit diperluas, jadi ada objek. Objek adalah kumpulan atribut, dan atribut itu sendiri dapat menjadi objek. Oleh karena itu objek dapat dibangun secara sewenang -wenang cukup kompleks untuk mewakili berbagai hal.
Tetapi terkadang hal -hal yang rumit dan bukan hal yang baik. Misalnya, tidak semua orang punya waktu, kesabaran, atau kebutuhan untuk membacanya dari awal hingga akhir. Biasanya itu cukup untuk hanya memahami pikirannya yang sentral. Jadi makalah ini memiliki kata kunci dan ikhtisar. Hal yang sama berlaku untuk objek dalam JavaScript. Kita perlu memiliki sarana untuk memahami karakteristik utamanya, sehingga objek memiliki metode tostring () dan valueof ().
Metode tostring () digunakan untuk mendapatkan deskripsi teks dari objek; dan metode nilai () digunakan untuk mendapatkan nilai eigen dari objek.
Tentu saja, ini hanya pemahaman saya sendiri. Juga, seperti namanya, metode tostring () cenderung mengembalikan string. Bagaimana dengan metode nilai ()? Menurut deskripsi dalam spesifikasi, ia cenderung mengembalikan angka - meskipun dalam tipe bawaan, metode ValueOf () hanya mengembalikan angka dan tanggal.
Menurut Gambar 1, ketika suatu objek dibandingkan dengan non-objek, objek perlu dikonversi menjadi tipe primitif (meskipun ketika dibandingkan dengan tipe boolean, tipe boolean perlu dikonversi menjadi tipe numerik terlebih dahulu, tetapi tipe objek perlu dikonversi menjadi tipe primitif berikutnya). Ini juga masuk akal. Lagi pula, == tidak benar -benar perbandingan yang sama. Kami hanya perlu mengambil fitur utama objek untuk berpartisipasi dalam operasi, dan mengesampingkan fitur sekunder.
Enam. Semuanya dihitung
Mari kita lihat kembali Gambar 1. Garis yang ditandai N atau P di dalamnya tidak memiliki arah. Jika kita menandai panah pada jalur ini, titik koneksi dari ujung bertanda N atau P ke ujung lainnya, maka kita akan mendapatkan (tidak mempertimbangkan tidak terdefinisi dan nol):
Sudahkah Anda menemukan sesuatu? Ya, selama proses perhitungan, semua jenis nilai memiliki kecenderungan untuk dikonversi ke tipe numerik. Lagipula, seorang selebriti pernah berkata:
Semuanya dihitung.
7. Beri aku berangan
Ada terlalu banyak omong kosong di masa lalu, jadi di sini ada contoh untuk membuktikan bahwa Gambar 1 memang nyaman dan efektif untuk membimbing praktik.
Contoh, Hitung yang berikut:
[''] == false
Pertama, kedua operan masing -masing adalah tipe objek dan tipe boolean. Menurut Gambar 1, perlu untuk mengonversi tipe boolean menjadi tipe numerik, dan hasil dari konversi false menjadi numerik adalah 0, sehingga ekspresi menjadi:
[''] == 0
Kedua operan menjadi tipe objek dan tipe numerik. Menurut Gambar 1, tipe objek perlu dikonversi ke tipe asli:
Pertama, hubungi [] .valueof (). Karena metode () metode array kembali, hasilnya bukan tipe asli. Terus hubungi [] .toString ().
Untuk array, algoritma metode tostring () adalah untuk mengubah setiap elemen menjadi jenis string dan kemudian menggabungkannya dengan ',', sehingga hasil akhirnya adalah string kosong, yang merupakan nilai dari jenis asli.
Pada titik ini, ekspresi menjadi:
'' == 0
Kedua operan menjadi jenis string dan tipe numerik. Menurut Gambar 1, tipe string perlu dikonversi ke tipe numerik. Seperti yang disebutkan sebelumnya, string kosong menjadi sejumlah 0. Jadi ekspresi menjadi:
0 == 0
Sejauh ini, jenis kedua operan akhirnya sama, dan hasilnya jelas benar.
Dari contoh ini, kita dapat melihat bahwa untuk menguasai aturan operasi ==, selain mengingat Gambar 1, kita juga perlu mengingat aturan metode tostring () dan nilai () dari objek bawaan tersebut. Termasuk objek, array, tanggal, nomor, string, boolean, dll.
8. Mari kita ringkas
Pernyataan sebelumnya sangat membingungkan. Di sini saya akan merangkum aturan == operasi yang dinyatakan dalam Gambar 1:
Hasil dari tidak terdefinisi == NULL adalah benar. Hasil perbandingan mereka dengan semua nilai lain adalah salah.
Ketika string == angka, string dikonversi ke angka.
Nilai boolean == Ketika jenis lain digunakan, nilai boolean dikonversi ke angka.
Saat objek == numerik/string, objek dikonversi ke tipe primitif.
Akhirnya, saya mengubah gambar menjadi hiburan saja :)
Oke, sudah berakhir. Jika Anda pikir artikel ini berguna bagi Anda, harap menyukainya sehingga lebih banyak orang dapat melihatnya.
Selain itu, silakan tunjukkan kekeliruan dalam artikel ini.