if([] == false) alert('empty array is false');
alert(+[]) // alert 0
if([]) alert('empty array is true');
Оба они будут запускать оповещение
if([] == false) alert('empty array is false');
alert(+[]) // alert 0
if([]) alert('empty array is true');
Оба они будут запускать оповещение
Оба текущих ответа здесь верны, но я хотел бы добавить более подробное объяснение, основанное на спецификации языка. Причиной явно противоречивых результатов является то, что операторы if
и сравнения сравнений оцениваются по-разному.
В случае оператора if(expression)
выражение оценивается, а затем преобразуется в булевский тип (§ 12.5). Массивы - это объекты, а когда объект преобразуется в булево, результат всегда true
(§ 9.2).
Сравнения равенства с ==
следуют другому набору правил, подробно описанному в § 11.9.3. Для сравнения может потребоваться несколько преобразований типов, пока оба операнда будут одного и того же типа. Порядок операндов также важен. Согласно этому алгоритму мы можем видеть, что сравнение [] == false
на самом деле представляет собой четырехступенчатую операцию:
Здесь задействован булеан, поэтому он сначала преобразуется в число (шаг 7 алгоритма). Так оно и делается:
[] == 0
Затем массив преобразуется в его примитивное значение (см. § 9.1 и § 8.12.8) и становится пустой строкой (шаг 9). Итак:
"" == 0
При сравнении строки с номером строка сначала преобразуется в номер (шаг 5, следуя правилам, описанным в § 9.3.1):
0 == 0
true
согласно шагу 1.c.iii.Это связано с типом принуждения оператора ==
(равенства).
Пустой массив считается правдивым (как пустой объект), поэтому вызывается второе предупреждение.
Однако, если вы используете ([] == false)
, ваш массив принуждается к его строковому представлению *, который является ""
, который затем считается значением ложности, что делает условие истинным, тем самым вызывая также первое предупреждение.
Если вы хотите избежать принуждения типа, вы должны использовать оператор ===
(identity), который является предпочтительным, и знаменитым Douglas Crockford продвинутый способ сравнения в javascript.
Подробнее об этом можно прочитать в этом исчерпывающем ответе.
* (Object.prototype.toString
вызывается на нем)
EDIT: весело с JS-сравнением:
NaN == false // false
NaN == true // also false
NaN == NaN // false
if(NaN) // false
if(!NaN) // true
0 == '0' // true
'' == 0 // true
'' == '0' // false !
Это показывает реальную "силу" сравнения с ==
из-за странных правил, упомянутых в ответе bfavarettos.
Существует разница между оценкой значения как булевым и его сопоставлением с true
или false
.
Используя оператор ==
, значения преобразуются так, чтобы соответствующие типы соответствовали. Значение []
, преобразованное в пустую строку ""
, и преобразование, которое, в свою очередь, к булеву, дает false
, поэтому [] == false
становится истинным.
Оценка []
в качестве логического значения вернет true
, потому что это не значение "ложь", то есть 0
, false
, null
, ""
, NaN
или undefined
.