JavaScript: matriz vacía, [] se evalúa como verdadero en estructuras condicionales. ¿Por qué es esto?

101

Encontré muchos errores en mi código porque esperaba esta expresión:

Boolean([]); evaluar como falso.

Pero este no fue el caso, ya que se evaluó como verdadero.

Por lo tanto, funciones que posiblemente regresaron []así:

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

}else
{
  // ...
}

no hizo las cosas esperadas.

¿Me equivoco al asumir que es []una matriz vacía?

Además, ¿este comportamiento es coherente en todos los navegadores? ¿O también hay trampas? Por cierto, observé este comportamiento en Goolgle Chrome.

racl101
fuente
5
las matrices son objetos, los objetos son verdaderos. solo pregunte por array.length, si no es cero, será veraz. cuando se convierte explícitamente a booleano, la matriz se convierte primero en una cadena vacía, luego la cadena vacía se convierte en falsa.
dandavis
1
¿Por qué no lo usas myCollection.length > 0?
Steve
1
@Steve: eso no funcionará si myCollectionresulta ser nullo undefined. Necesitas usar if(myCollection && myCollection.length > 0).
Ted Hopp
@TedHopp - por supuesto ... solo estaba señalando que myCollection.length > 0ofrece un valor booleano que está haciendo lo que pidió el OP ... todavía necesita hacer el trabajo desde allí.
Steve
3
posible duplicado de la matriz vacía
bummi

Respuestas:

120

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

Los siguientes valores son siempre falsos:

  • falso
  • 0 (cero)
  • "" (cuerda vacía)
  • nulo
  • indefinido
  • NaN (un valor numérico especial que significa ¡No es un número!)

Todos los demás valores son verdaderos, incluidos "0" (cero entre comillas), "falso" (falso entre comillas), funciones vacías, matrices vacías y objetos vacíos.

Con respecto a por qué esto es así, sospecho que se debe a que las matrices de JavaScript son solo un tipo particular de objeto. El tratamiento especial de las matrices requeriría una sobrecarga adicional para probar Array.isArray(). Además, probablemente sería confuso si las matrices verdaderas se comportaran de manera diferente a otros objetos similares a matrices en este contexto, mientras que hacer que todos los objetos similares a matrices se comporten de la misma manera sería aún más caro.

Barmar
fuente
28
Si prueba la expresión a la que [] == falsese evalúa true.
m.rufca
Hay una tabla que muestra situaciones inesperadas usando el ==comparador en el enlace que publicó. Comenté solo para tener cuidado al esperar una evaluación verdadera o falsa.
m.rufca
4
Esto realmente no responde a la pregunta, que era POR QUÉ. ¿Por qué una matriz vacía es verdadera, cuando una cadena vacía es falsa? Como decisión de diseño deliberada, esto se siente muy mal.
Esa Lindqvist
1
Quizás, porque se requiere que actúen como los objetos primitivos. Pero Javascript no tiene matrices primitivas.
Barmar
28

Debería verificar el .lengthde esa matriz para ver si contiene algún elemento.

if (myCollection) // always true
if (myCollection.length) // always true when array has elements
if (myCollection.length === 0) // same as is_empty(myCollection)
DevlshOne
fuente
@marczellm Ese comentario de Steve está desactualizado, notificó a DevIshOne sobre la condición que faltaba "cuando la matriz tiene elementos" , que por lo tanto se corrigió en la edición .
mucaho