Подтвердить что ты не робот

Почему if ([]) проверяется, а [] == false в javascript?

if([] == false) alert('empty array is false');
alert(+[]) // alert 0
if([]) alert('empty array is true');

Оба они будут запускать оповещение

Демо

4b9b3361

Ответ 1

Оба текущих ответа здесь верны, но я хотел бы добавить более подробное объяснение, основанное на спецификации языка. Причиной явно противоречивых результатов является то, что операторы 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.

Ответ 2

Это связано с типом принуждения оператора == (равенства).

Пустой массив считается правдивым (как пустой объект), поэтому вызывается второе предупреждение.

Однако, если вы используете ([] == 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.

Ответ 3

Существует разница между оценкой значения как булевым и его сопоставлением с true или false.

Используя оператор ==, значения преобразуются так, чтобы соответствующие типы соответствовали. Значение [], преобразованное в пустую строку "", и преобразование, которое, в свою очередь, к булеву, дает false, поэтому [] == false становится истинным.

Оценка [] в качестве логического значения вернет true, потому что это не значение "ложь", то есть 0, false, null, "", NaN или undefined.