JavaScript: пустой массив, [] в условных структурах принимает значение true. Почему это?

101

Я столкнулся с множеством ошибок в своем коде, потому что ожидал этого выражения:

Boolean([]); оценить как ложь.

Но это было не так, поскольку оно было оценено как истина.

Следовательно, функции, которые, возможно, вернулись []так:

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

}else
{
  // ...
}

не делал ожидаемых вещей.

Я ошибаюсь, предполагая, что []это пустой массив?

Кроме того, одинаково ли такое поведение во всех браузерах? Или тут тоже есть подводные камни? Кстати, я наблюдал такое поведение в Goolgle Chrome.

racl101
источник
5
массивы - это объекты, объекты - истинные. просто попросите array.length, если не ноль, это будет правдой. при явном преобразовании в логическое значение массив сначала превращается в пустую строку, а затем пустая строка превращается в ложь.
dandavis 02
1
Почему ты не используешь myCollection.length > 0?
Стив
1
@ Стив - это не сработает, если myCollectionслучится nullили undefined. Вам нужно использовать if(myCollection && myCollection.length > 0).
Тед Хопп
@TedHopp - конечно ... Я только что указывал, что myCollection.length > 0предлагает логическое значение, которое выполняет то, что запросил OP ... ему все еще нужно выполнять работу оттуда.
Стив

Ответы:

120

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

Следующие значения всегда ложны:

  • ложный
  • 0 (ноль)
  • "" (пустой строкой)
  • значение NULL
  • неопределенный
  • NaN (специальное числовое значение, означающее не-число!)

Все остальные значения истинны, включая «0» (ноль в кавычках), «false» (ложь в кавычках), пустые функции, пустые массивы и пустые объекты.

Что касается того, почему это так, я подозреваю, что это потому, что массивы JavaScript - это просто особый тип объекта. Специальная обработка массивов потребует дополнительных накладных расходов на тестирование Array.isArray(). Кроме того, вероятно, было бы запутанно, если бы истинные массивы вели себя иначе, чем другие объекты, подобные массиву, в этом контексте, в то время как заставить все подобные массивы объекты вести себя одинаково было бы еще дороже.

Barmar
источник
28
Если вы проверите выражение, которое [] == falseоно оценивает true.
m.rufca
3
@ m.rufca См. stackoverflow.com/questions/5491605/…
Barmar
==в опубликованной вами ссылке есть небольшая таблица, показывающая неожиданные ситуации с использованием компаратора. Я прокомментировал, чтобы быть осторожным, ожидая истинной или ложной оценки.
m.rufca
4
Это не совсем ответ на вопрос, ПОЧЕМУ. Почему пустой массив правдив, а пустая строка - ложь? Как сознательное дизайнерское решение, это очень плохо.
Эса Линдквист
1
Может быть, потому что они должны действовать как примитивные объекты. Но в Javascript нет примитивных массивов.
Barmar
28

Вы должны проверить .lengthэтот массив, чтобы увидеть, содержит ли он какие-либо элементы.

if (myCollection) // always true
if (myCollection.length) // always true when array has elements
if (myCollection.length === 0) // same as is_empty(myCollection)
DevlshOne
источник
@marczellm Этот комментарий Стива устарел, он уведомил DevIshOne об отсутствующем условии «когда в массиве есть элементы» , что было исправлено при редактировании .
mucaho