JavaScript: larik kosong, [] mengevaluasi ke true dalam struktur bersyarat. Kenapa ini?

100

Saya menemukan banyak bug dalam kode saya karena saya mengharapkan ungkapan ini:

Boolean([]); untuk mengevaluasi salah.

Tetapi ini tidak terjadi karena dianggap benar.

Oleh karena itu, fungsi yang mungkin dikembalikan []seperti ini:

// Where myCollection possibly returned [ obj1, obj2, obj3] or []
if(myCollection)
{
  // ...

}else
{
  // ...
}

tidak melakukan hal-hal yang diharapkan.

Apakah saya salah dalam mengasumsikan bahwa []array kosong?

Selain itu, Apakah perilaku ini konsisten di semua browser? Atau ada gotcha di sana juga? Saya mengamati perilaku ini di Goolgle Chrome.

racl101
sumber
5
array adalah objek, objek adalah kebenaran. minta saja array.length, jika bukan nol, itu akan benar. ketika Anda secara eksplisit mengonversi ke Boolean, larik berubah menjadi string kosong terlebih dahulu, kemudian string kosong berubah menjadi salah.
dandavis
1
Mengapa Anda tidak menggunakan myCollection.length > 0?
Steve
1
@ Steve - itu tidak akan berhasil jika myCollectionkebetulan nullatau undefined. Anda perlu menggunakan if(myCollection && myCollection.length > 0).
Ted Hopp
@TedHopp - tentu saja ... Saya baru saja menunjukkan bahwa myCollection.length > 0menawarkan nilai boolean yaitu melakukan apa yang diminta OP ... dia masih perlu melakukan pekerjaan dari sana.
Steve

Jawaban:

119

Dari http://www.sitepoint.com/javascript-truthy-falsy/

Nilai berikut selalu salah:

  • Salah
  • 0 (nol)
  • "" (string kosong)
  • batal
  • tidak terdefinisi
  • NaN (nilai Angka khusus yang berarti Bukan-Angka!)

Semua nilai lainnya adalah benar, termasuk "0" (nol dalam tanda kutip), "salah" (salah dalam tanda kutip), fungsi kosong, larik kosong, dan objek kosong.

Mengenai mengapa demikian, saya menduga itu karena array JavaScript hanyalah jenis objek tertentu. Memperlakukan array secara khusus akan membutuhkan overhead ekstra untuk mengujinya Array.isArray(). Juga, mungkin akan membingungkan jika array sebenarnya berperilaku berbeda dari objek serupa array lainnya dalam konteks ini, sementara membuat semua objek seperti array berperilaku sama akan lebih mahal.

Barmar
sumber
28
Jika Anda menguji ekspresi [] == falseyang dievaluasi true.
m.rufca
3
@ m.rufca Lihat stackoverflow.com/questions/5491605/…
Barmar
Ada beberapa tabel yang menunjukkan situasi tak terduga menggunakan ==pembanding di tautan yang Anda posting. Saya berkomentar hanya untuk berhati-hati ketika mengharapkan evaluasi benar atau salah.
m.rufca
4
Ini tidak benar-benar menjawab pertanyaan, yaitu MENGAPA. Mengapa array kosong benar, ketika string kosong salah? Sebagai keputusan desain yang disengaja, ini terasa sangat buruk.
Esa Lindqvist
1
Mungkin, karena itu diperlukan untuk bertindak seperti objek primitif. Tetapi Javascript tidak memiliki array primitif.
Barmar
28

Anda harus memeriksa .lengtharray itu untuk melihat apakah itu berisi elemen apa pun.

if (myCollection) // always true
if (myCollection.length) // always true when array has elements
if (myCollection.length === 0) // same as is_empty(myCollection)
DevlshOne
sumber
@marczellm Komentar dari Steve sudah kedaluwarsa, dia memberi tahu DevIshOne tentang kondisi yang hilang "ketika array memiliki elemen" , yang karenanya diperbaiki dalam pengeditan .
mucaho