Усі значення фальси в JavaScript


215

Які значення в JavaScript є "falsey" , тобто вони виражають як помилкові у виразах, як if(value), value ?і !value?


Вже є деякі дискусії про призначення фальсифікованих значень на стеку Overflow , але жодної вичерпної повної відповіді, у якій перелічено всі значення фальси.

Я не зміг знайти жодного повного списку в MDN JavaScript Reference , і я здивовано виявив, що найкращими результатами при пошуку повного, авторитетного списку значень фальси в JavaScript були статті блогу, деякі з яких мали явні упущення (наприклад, NaN), і жоден з них не мав такого формату, як Stack Overflow, де можна додавати коментарі або альтернативні відповіді, щоб вказати на примхи, сюрпризи, упущення, помилки чи застереження. Отже, здавалося, має сенс зробити таке.




5
dorey.github.io/JavaScript-Equality-Table - це чудовий ресурс і має if()вкладку для правдивості.
cloudfeet

4
Нічого, дуже корисно, дякую! [[]] == ""але [] != []? У мене болить голова ...
користувач56reinstatemonica8

Специфікація ECMA 262 детально описує ці правила порівняння, зокрема секції 11.9.1 - 11.9.6: ecma-international.org/ecma-262/5.1/#sec-11.9.3 Було б непогано, якби ви оновили свою відповідь, щоб включити цю посилання , оскільки він забезпечує правила того, як слід (як передбачається) робити істинні / помилкові визначення.
Шон Вілсон

Відповіді:


367

Значення Falsey в 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 року) (єдиними змінами після першої специфікації сценарію ECMA в 1997 році є додавання символів ES6 , які завжди є непростими, і BigInt, згадане вище:

Не визначено: повернути помилково.  Нуль: Повернення помилково.  Булев: аргумент повернення.  Число: Якщо аргумент +0, -0 або NaN, поверніть false;  інакше повернути справжню.  Рядок: Якщо аргументом є порожній рядок (його довжина дорівнює нулю), поверніть 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

"Truthy" просто означає, що 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
  • Будь-які подібні конструкції, які дають вам помилково рівне значення, загорнуте у тип "truthy"
  • [], [[]]і [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в порівнянні один з одним ==.


3
FYI, які !, ifі ?..:мають в загальному , що вони називають внутрішню ToBooleanфункцію за значенням. Як ці цінності ведуть себе в контексті !, ifі т.д., вже має на увазі їх назва: вони «falsy» значення. Я трохи боюся , що інші будуть читати відповідь і думають : «Про , так в цьому контексті ( !, if, ?...:), то значення false, але !!, це true» , але не розумію основну концепції. Ще два моменти: 1) v ? true : false- це просто багатослівний спосіб !!v. 2) typeof завжди повертає не порожній рядок, який є truthy.
Фелікс Клінг

1
Тобто немає сенсу дивитись typeof nullабо typeof undefinedконкретно. Ви можете просто сказати, що непусті рядки є правдою.
Фелікс Клінг

1
Я бачу, але це не має нічого спільного з оригінальним запитанням;) Додавання занадто багато пов'язаної, але не відповідної інформації може бути досить заплутаною для читачів.
Фелікс Клінг

5
Я щойно дізнався, що document.allце помилково .
Клавдіу

3
Що стосується вільного порівняння: оскільки булеві перетворюються на числа, x == falseвиклик, ToNumber(x)який дуже сильно відрізняється від ToBoolean(x). Можливо, варто пояснити. Також я щойно помітив, що я вже коментував цю відповідь століттями тому: D
Фелікс Клінг,

3

Не забувайте про не порожній рядок, "false"який оцінюєtrue


8
… І, отже, не є хибною цінністю, про яку вимагали?
Бергі

5
дотик. це значення, яке ви можете розраховувати на фальси, а це не так, про що все-таки варто пам’ятати, і, я думаю, заслуговує на згадку у вичерпному списку
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.


7
У JavaScript немає цілих чисел. 0, 0x0, 0.0І 0.00просто різні литералов для однієї і тієї ж IEEE-754 64-бітного нульового значення з плаваючою комою.
fredoverflow

1

На додаток до теми, оскільки для ES2020 у нас є нове значення, яке є помилковим, це BigInt zero (0n):

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

Таким чином, тепер у нас є 7 "хибних" значень (не включаючи document.all, як згадував користувач вище, оскільки це частина DOM, а не JS).


1
Приємно! Дякую, я про це ще не чув, я додав його у великий список із посиланням, яке підтверджує вашу відповідь за його підвищення
user56reinstatemonica8
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.