Все значения Falsey в JavaScript

215

Какие значения в JavaScript являются «ложными» , что означает, что они оцениваются как ложные в выражениях типа if(value), value ?и !value?


Есть некоторые дискуссии о назначении значений Falsey для переполнения стека , но нет исчерпывающего полного ответа, в котором перечислены все значения Falsey.

Я не смог найти полный список в Справочнике по MDN JavaScript , и с удивлением обнаружил, что лучшими результатами при поиске полного, достоверного списка значений Falsey в JavaScript были статьи в блогах, некоторые из которых имели очевидные упущения (например, NaN), и ни один из которых не имел такого формата, как переполнение стека, в котором можно было бы добавить комментарии или альтернативные ответы, чтобы указать на причуды, неожиданности, упущения, ошибки или предостережения. Таким образом, казалось, имеет смысл сделать один.

user56reinstatemonica8
источник
1
@tibos blog.stackoverflow.com/2011/07/...
user56reinstatemonica8
5
dorey.github.io/JavaScript-Equality-Table - отличный ресурс, в котором есть if()вкладка для правдивости.
облачные ноги
4
Вау, действительно полезно, спасибо! [[]] == ""но [] != []? У меня болит голова ...
user56reinstatemonica8
Спецификация ECMA 262 детализирует эти правила сравнения, в частности, с 11.9.1 по 11.9.6: ecma-international.org/ecma-262/5.1/#sec-11.9.3. Было бы здорово , если бы вы обновили свой ответ, включив эту ссылку , поскольку он предоставляет правила того, как выполняются (должны быть) истинные / ложные определения.
Шон Уилсон

Ответы:

367

Ложные значения в JavaScript

  • false
  • Ноль Numberтипа: 0а также -0, 0.0и шестигранная форма 0x0( благодаря RBT )
  • Ноль BigIntтипа: 0nи -0n(новое в 2020 году, спасибо GetMeARemoteJob )
  • "", ''И ``- строки длины 0
  • null
  • undefined
  • NaN
  • document.all (только в браузерах HTML)

«Falsey» просто означает, что внутренняя ToBooleanфункция JavaScript возвращается false. ToBooleanлежит в основе !value, value ? ... : ...;и if (value). Вот его официальная спецификация (рабочий проект 2020 года) (единственными изменениями с самой первой спецификации ECMAscript в 1997 году являются добавление символов ES6 , которые всегда соответствуют действительности, и BigInt, как уже упоминалось выше:

Undefined: вернуть false.  Null: вернуть false.  Boolean: вернуть аргумент.  Number: Если аргумент равен +0, -0 или NaN, вернуть false;  в противном случае верните истину.  String: если аргумент является пустой строкой (ее длина равна нулю), вернуть false;  в противном случае верните истину.  BigInt: если аргумент равен 0n, вернуть false;  в противном случае верните истину.  Символ: Вернуть истину.  Объект: Вернуть истину.


Сравнения с ==(слабое равенство)

Стоит поговорить о ложных сравнениях с== ложными значениями , которые используют ToNumber()и могут вызвать некоторую путаницу из-за основных различий. Они эффективно образуют три группы:

  • false, 0, -0, "", '' все соответствуют друг другу с ==
    • например false == "", '' == 0и, следовательно,4/2 - 2 == 'some string'.slice(11);
  • null, undefined совпадать с ==
    • например, null == undefinedноundefined != false
    • Стоит также упомянуть, что пока typeof nullвозвращается 'object',null это не объект, это давняя ошибка / причуда , которая не была установлена для того , чтобы обеспечить совместимость. Это не настоящий объект, и объекты являются правдивыми (за исключением того "преднамеренного нарушения", document.allкогда Javascript реализован в HTML)
  • NaN ничего не соответствует, с ==или ===даже сам по себе не
    • например NaN != NaN , NaN !== NaN, NaN != false,NaN != null

При «строгом равенстве» ( ===) таких группировок нет. Только false === false.

Это одна из причин, по которой многие разработчики и многие руководства по стилю (например, standardjs ) предпочитают ===и почти никогда не используют ==.


Истинные ценности, которые на самом деле == false

«Правда» означает, что внутренняя ToBooleanфункция JavaScript возвращается true. Причудливый Javascript, о котором нужно знать (и еще одна веская причина, чтобы предпочесть=== более ==): это возможно значение , которое должно быть truthy ( ToBooleanвозвращается true), но и == false.

Ты можешь подумать if (value && value == false) alert('Huh?') это логическая невозможность, которая не может произойти, но это произойдет для:

  • "0"и '0'- это непустые строки, которые являются правдивыми, но Javascript ==сопоставляет числа с эквивалентными строками (например 42 == "42"). поскольку0 == false , если "0" == 0, "0" == false.
  • new Number(0) и new Boolean(false) - это объекты, которые правдивы, но ==видят свои ценности, которые == false.
  • 0 .toExponential(); - объект с числовым значением, эквивалентным 0
  • Любые подобные конструкции, которые дают вам ложно-выравнивающее значение, заключенное в тип, который является правдивым
  • [], [[]]И [0](спасибо cloudfeet за ссылку Таблица JavaScript равенства )

Еще несколько правдивых ценностей

Это всего лишь несколько ценностей, которые некоторые люди могут считать ложными, но на самом деле они правдивы.

  • -1 и все ненулевые отрицательные числа
  • ' ', " ", "false", 'null'... все непустые строки, в том числе строк, которые только пробельные
  • Все typeof, что от , которое всегда возвращает непустую строку, например:

  • Любой объект (кроме этого «преднамеренного нарушения» document.allв браузерах; помните, что на nullсамом деле это не объект, несмотря на typeofпредположение об обратном). Включая:

    • {}
    • []
    • function(){}или () => {}(любая функция, включая пустые функции)
    • Error и любой случай Error
    • Любое регулярное выражение
    • Все, что создано с помощью new(в том числе new Number(0)и new Boolean(false))
  • Любой символ

true, 1, "1"И [1]возвращение trueпо сравнению друг с другом ==.

user56reinstatemonica8
источник
3
FYI, какие !, ifи ?..:имеют в общем , что они называют внутреннюю ToBooleanфункцию по значению. Как эти ценности ведут себя в контексте !, ifи т.д., уже подразумевает их название: они «falsy» значения. Я немного боюсь , что другие будут читать ответ и думают : «О , так в этом контексте ( !, if, ?...:), то значение false, но !!, это true» , но не понимаю основную концепции. Два других момента: 1) v ? true : falseэто просто многословный способ !!v. 2) typeof всегда возвращает непустую строку, что является правдой.
Феликс Клинг
1
Т.е. нет смысла смотреть typeof nullили typeof undefinedконкретно. Вы могли бы просто сказать, что непустые строки правдивы.
Феликс Клинг
1
Я вижу, но это не имеет ничего общего с первоначальным вопросом;) Добавление слишком много связанной, но не относящейся к делу информации может быть довольно запутанным для читателей.
Феликс Клинг
5
Я только что узнал, что document.allэто тоже обман .
Клаудиу
3
Что касается свободного сравнения: потому что логические значения преобразуются в числа, x == falseвызов ToNumber(x)будет просто очень отличается от ToBoolean(x). Возможно, стоит объяснить. Также я только что заметил, что уже прокомментировал этот ответ давным-давно: D
Феликс Клинг
3

Не забывайте о непустой строке, "false"которая оценивается какtrue

MrMcPlad
источник
8
... и, следовательно, не является ли ложной ценностью, о которой спрашивали?
Берги
5
Touche. это значение, которое вы могли бы ожидать от фальши, а не таковое, о котором все еще стоит знать, и я думаю, заслуживает упоминания в полном списке
MrMcPlad
4
Добавлен в список ... но давайте не будем пытаться превратить это в исчерпывающий список всех возможных истинных значений! Это займет некоторое время:-)
user56reinstatemonica8
3

Просто чтобы добавить в список ложных значений @ user568458:

  • В дополнение к целому числу 0 десятичное число 0,0, 0,00 или любое такое нулевое число также является ложным значением.

    var myNum = 0.0;
    if(myNum){
        console.log('I am a truthy value');
    }
    else {
        console.log('I am a falsy value');
    }

    Вышеупомянутые фрагменты кода I am a falsy value

  • Аналогично, шестнадцатеричное представление числа 0 также является ложным значением, как показано в следующем фрагменте кода:

    var myNum = 0x0; //hex representation of 0
    if(myNum){
        console.log('I am a truthy value');
    }   
    else {
        console.log('I am a falsy value');
    }

    Над фрагментом кода снова печатается I am a falsy value.

RBT
источник
7
JavaScript не имеет целых чисел. 0, 0x0, 0.0И 0.00просто разные литералов для одной и той же IEEE-754 64-битного нулевого значения с плавающей запятой.
fredoverflow
1

В дополнение к теме, с ES2020 у нас есть новое значение, которое ложно, это BigInt ноль (0n):

0n == false // true
-0n == false // true

Таким образом, теперь у нас есть всего 7 «ложных» значений (не считая document.all, как упоминалось пользователем выше, поскольку он является частью DOM, а не JS).

GetMeARemoteJob
источник
1
Ницца! Спасибо, я еще не слышал об этом, я добавил его в большой список со ссылкой на ваш ответ за повышение
user56reinstatemonica8