Mengapa “,,,” == Array (4) di Javascript?

119

Boot interpreter / konsol Anda dan coba perbandingannya

> ",,," == Array(4)
True

Mengapa? Pada awalnya saya berpikir mungkin karena Anda dapat memikirkan ",,," sebagai larik empat karakter dengan potongan penghentian '\ 0', mungkin itu sebabnya, tapi

> "..." == Array(4)

Menampilkan "False". Jadi kenapa? Saya tahu itu adalah sedikit lelucon aneh yang mengetik di Javascript, tapi hanya ingin tahu apa yang menggarisbawahi perilaku ini. Diperoleh ini dari presentasi Zed Shaw yang luar biasa di sini btw .

ZenLikeThat
sumber
14
Beberapa bahasa selain C menggunakan zero-termination dengan cara yang terlihat oleh programmer.
Joey
7
Jika saya boleh bertanya, apa yang mengarah pada penemuan ini?
SomeKittens
1
@SomeKittens Zed Shaw menyebutkan hal ini secara eksplisit dalam video yang saya tautkan dalam pertanyaan saya (sebagai kritik terhadap Javascript). Bersulang!
ZenLikeThat
5
@SomeKittens Ini juga disebutkan dalam pembicaraan "wat" (cukup terkenal), menunjukkan beberapa kebiasaan di Ruby dan JavaScript destroyallsoftware.com/talks/wat
Cronco
5
Ini adalah salah satu dari banyak alasan bagus untuk selalu menggunakan ===daripada ==.
wprl

Jawaban:

178

Karena operan tangan kanan diubah menjadi string dan representasi string Array(4)adalah ,,,:

> Array(4).toString()
  ",,,"

Jika Anda menggunakan fungsi konstruktor larik dan meneruskan angka, itu akan menyetel panjang larik ke angka itu. Jadi Anda dapat mengatakan Anda memiliki empat indeks kosong (sama seperti [,,,]) dan representasi string default dari array adalah daftar elemennya yang dipisahkan koma:

> ['a','b','c'].toString()
  "a,b,c"

Bagaimana perbandingan tersebut bekerja dijelaskan dalam bagian 11.9.3 spesifikasi . Di sana Anda akan melihat ( x == y):

8. Jika Type ( x ) adalah String atau Number dan Type ( y ) adalah Objek,
kembalikan hasil perbandingan x == ToPrimitive ( y ).

(array adalah objek dalam JavaScript)

dan jika Anda mengikuti ToPrimitivemetode tersebut, Anda akhirnya akan menemukan bahwa metode itu memanggil toString.

Felix Kling
sumber
2
Oke, sekarang ini semua masuk akal bagi saya. Terima kasih.
ZenLikeThat
6
Yang, pada gilirannya, adalah karena array merangkai seolah-olah sedang mereka gunakan Array.join(",").
senja -tidak aktif-
Anda harus bersabar untuk memprogram dalam javascript
matcheek
31

Secara internal berjalan

",,," == Array(4).toString()
Jason Kulatunga
sumber
31

Coba gunakan ===. Saat menggunakan ==dalam Javascript, itu akan mencoba untuk mentransmisikan variabel, sehingga menyebabkan masalah seperti ini. Konsol mentransmisikan Array(4)ke representasi string (yaitu Array(4).toString), yaitu ",,,". Alasan adanya koma adalah karena .toString()fungsi menambahkannya ke item terpisah dalam larik.

Lihat cuplikan di bawah ini:

document.write( Array(4).toString() );

SomeKittens
sumber
18

Ini karena Array(4)menginisialisasi array dari 4 nilai kosong, yang ==secara implisit mengonversi, jadi:

 ",,," == Array(4)

 ",,," == Array(4).toString()

 ",,," == ["", "", "", ""] // note 3 commas for 4 values

 ",,," == ["", "", "", ""].toString()

Semuanya serupa.

==melakukan konversi jenis implisit sebelum membandingkan nilai, yang dapat menghasilkan hasil yang tidak dapat diprediksi. Gunakan ===untuk memeriksa jenis dan nilainya.

Keith
sumber
5

Membandingkan Array dengan string memaksa Array menjadi string sebelum melakukan perbandingan. Memaksakan Array 4-elemen kosong ke string menghasilkan string yang sama persis.

Russell Borogove
sumber
4

Saya pertama kali mengira itu adalah sesuatu dengan "prototipe" ... tetapi setelah sedikit penyelidikan saya mencapai kesimpulan yang menyedihkan ...

Rupanya itu adalah hal js internal dan lebih tidak jelas dengan tidak banyak logika ...

Coba saja

Array(4)==Array(4)

dan tidak ada paksaan pada tipe juga ...

Array(4)===Array(4)

dan Anda akan mendapatkan FALSE

Anda tahu itu null==null, null===nulldan bahkan undefined==undefineddan undefined===undefinedmengembalikan TRUE ... jadi ... itu agak tidak jelas ...

Array(4)==[,,,] harus benar juga

ZEE
sumber
ZEE, Array (4) == [,,,] tidak akan benar. Jika kita membandingkan objek dengan primitif, maka objek tersebut akan diubah menjadi primitif. Itulah alasannya memanggil toString ().
devsathish
array (x) harus menjadi alamat konstruktor ... bagaimanapun, dalam sebuah sistem (jangan repot-repot sistem seperti apa), <identity_X> === <identity_X> akan selalu benar!
ZEE