Wszystkie wartości falsey w JavaScript

215

Jakie są wartości w JavaScript, które są „falsey” , co oznacza, że oceniają one jako fałszywe w wyrażeniach takich jak if(value), value ?i !value?


Jest już kilka dyskusji na temat celu wartości falsey na Stack Overflow , ale nie ma wyczerpującej pełnej odpowiedzi wymieniającej wszystkie wartości falsey.

Nie mogłem znaleźć żadnej pełnej listy w MDN JavaScript Reference i byłem zaskoczony, że najlepsze wyniki, gdy szukałem pełnej, wiarygodnej listy wartości falsey w JavaScript, to artykuły na blogu, z których niektóre zawierały oczywiste pominięcia (na przykład NaN), a żaden z nich nie miał formatu takiego jak Przepełnienie stosu, w którym można dodawać komentarze lub alternatywne odpowiedzi w celu wskazania dziwactw, niespodzianek, pominięć, błędów lub zastrzeżeń. Wydawało się, że sensowne jest stworzenie takiego.

user56reinstatemonica8
źródło
1
@tibos blog.stackoverflow.com/2011/07/…
user56reinstatemonica8
5
dorey.github.io/JavaScript-Equality-Table to świetny zasób i ma if()zakładkę na prawdziwość.
cloudfeet
4
Wow, naprawdę przydatne, dzięki! [[]] == ""ale [] != []? Boli mnie głowa ...
user56reinstatemonica8
Specyfikacja ECMA 262 wyszczególnia te zasady porównywania, w szczególności sekcje od 11.9.1 do 11.9.6: ecma-international.org/ecma-262/5.1/#sec-11.9.3 Byłoby bardzo dobrze, gdybyś zaktualizował swoją odpowiedź, aby uwzględnić to odniesienie , ponieważ zapewnia reguły dotyczące sposobu dokonywania (prawdziwych) fałszywych ustaleń.
Shaun Wilson,

Odpowiedzi:

367

Wartości Falsey w JavaScript

„Falsey” oznacza po prostu, że ToBooleanzwraca wewnętrzną funkcję JavaScript false. ToBooleantkwi u podstaw !value, value ? ... : ...;i if (value). Oto jego oficjalna specyfikacja (projekt roboczy 2020) (jedynymi zmianami od pierwszej specyfikacji ECMAscript w 1997 r. Są dodanie symboli ES6 , które zawsze są zgodne z prawdą i BigIntwspomniane powyżej:

Undefined: Zwraca false.  Null: zwraca false.  Boolean: Zwraca argument.  Liczba: Jeśli argument to +0, -0 lub NaN, zwróć false;  w przeciwnym razie zwróci true.  Łańcuch: Jeśli argument jest pustym łańcuchem (jego długość wynosi zero), zwróć false;  w przeciwnym razie zwróci true.  BigInt: Jeśli argument ma wartość 0n, zwróć wartość false;  w przeciwnym razie zwróci true.  Symbol: Return true.  Obiekt: Return true.


Porównania z ==(luźna równość)

Warto mówić o luźnych porównaniach== wartości fałszerstwa , które wykorzystują ToNumber()i mogą powodować pewne zamieszanie z powodu różnic leżących u ich podstaw. Skutecznie tworzą trzy grupy:

  • false, 0, -0, "", '' wszystkie pasują do siebie ==
    • na przykład false == "", '' == 0i dlatego4/2 - 2 == 'some string'.slice(11);
  • null, undefined pasuje do ==
    • np null == undefinedaleundefined != false
    • Warto też wspomnieć, że gdy typeof nullwróci 'object', nullto nie jest obiektem, jest to dawna bug / dziwactwo , że nie została ustalona w celu utrzymania kompatybilności. To nie jest prawdziwy obiekt, a obiekty są zgodne z prawdą (z wyjątkiem „umyślnego naruszenia”, document.allgdy JavaScript jest zaimplementowany w HTML)
  • NaN nie pasuje do niczego, ==ani ===nawet do siebie
    • np NaN != NaN, NaN !== NaN, NaN != false,NaN != null

W przypadku „ścisłej równości” ( ===) nie ma takich grupowań. Tylko false === false.

Jest to jeden z powodów, dla których wielu programistów i wiele przewodników po stylu (np. Standardjs ) preferuje ===i prawie nigdy nie używa ==.


Naprawdę to docenia == false

„Prawda” oznacza po prostu, że ToBooleanzwraca wewnętrzną funkcję JavaScript true. Zrządzenie JavaScript, żeby mieć świadomość (i kolejny dobry powód, aby wolą ===nad ==): jest to możliwe, to jest wartość nie będzie truthy ( ToBooleanwraca true), ale również == false.

Możesz pomyśleć, że if (value && value == false) alert('Huh?')jest to logiczna niemożliwość, która nie mogła się wydarzyć, ale tak będzie, ponieważ:

  • "0"i '0'- to niepuste ciągi, które są zgodne z prawdą, ale JavaScript ==dopasowuje liczby do równoważnych ciągów (np 42 == "42".). Od tego 0 == false, czy "0" == 0, "0" == false.
  • new Number(0)i new Boolean(false)- są przedmiotami, które są zgodne z prawdą, ale ==dostrzegają ich wartości, które == false.
  • 0 .toExponential(); - obiekt o wartości liczbowej równoważnej do 0
  • Wszelkie podobne konstrukcje, które dają fałszywie wyrównaną wartość opakowaną w typ, który jest prawdziwy
  • [], [[]]oraz [0](dzięki cloudfeet za link do tabeli równości JavaScript )

Niektóre bardziej prawdziwe wartości

To tylko kilka wartości, których niektórzy mogą się spodziewać, że są fałszywi, ale w rzeczywistości są prawdomówni.

  • -1 i wszystkie niezerowe liczby ujemne
  • ' ', " ", "false", 'null'... wszystkie niepuste ciągi, w tym strun, które są po prostu białe znaki
  • Wszystko typeof, co zawsze zwraca niepusty ciąg, na przykład:

  • Każdy obiekt (z wyjątkiem „umyślnego naruszenia” document.allw przeglądarkach; pamiętaj, że nulltak naprawdę nie jest to obiekt, mimo że typeofsugeruje inaczej). Włącznie z:

    • {}
    • []
    • function(){}lub () => {}(dowolna funkcja, w tym puste funkcje)
    • Error i każdy przypadek Error
    • Każde wyrażenie regularne
    • Wszystko utworzone za pomocą new(w tym new Number(0)i new Boolean(false))
  • Dowolny symbol

true, 1, "1"I [1]powrót truew stosunku do siebie nawzajem ==.

user56reinstatemonica8
źródło
3
FYI, co !, ifi ?..:mają wspólną cechą jest to, że nazywają wewnętrzną ToBooleanfunkcję na wartości. Jak zachowują się te wartości w kontekście !, ifitd już implikowane przez ich nazwy: Są „falsy” wartości. Jestem trochę boi się, że inni będą czytać odpowiedź i myślę : „O tak, w tym kontekście ( !, if, ?...:), to jest wartość nie jest false, ale !!jest to true , ale nie rozumie podstawowe pojęcia. Dwa inne punkty: 1) v ? true : falseto tylko pełny sposób !!v. 2) typeof zawsze zwraca niepusty ciąg, co jest zgodne z prawdą.
Felix Kling
1
Tj. Nie ma sensu patrzeć typeof nullani typeof undefinedkonkretnie. Można po prostu powiedzieć, że niepuste ciągi są zgodne z prawdą.
Felix Kling
1
Rozumiem, ale nie ma to nic wspólnego z pierwotnym pytaniem;) Dodanie zbyt dużej ilości powiązanych, ale nieistotnych informacji może być mylące dla czytelników.
Felix Kling
5
Właśnie się dowiedziałem, że document.allto też jest fałsz .
Claudiu
3
Odnośnie luźnego porównania: ponieważ booleany są konwertowane na liczby, x == falsezadzwoni, ToNumber(x)co jest zupełnie inne niż ToBoolean(x). Może warto to wyjaśnić. Właśnie zauważyłem, że skomentowałem tę odpowiedź wieki temu: D
Felix Kling
3

Nie zapomnij o niepustym ciągu, "false"który ma wartośćtrue

MrMcPlad
źródło
8
… A zatem czy nie jest to wartość fałszywa, o którą poproszono?
Bergi
5
touché. jest to wartość, której można się spodziewać, że jest falsey, i nie jest, o czym nadal warto wiedzieć, i myślę, że zasługuje na wzmiankę na wyczerpującej liście
MrMcPlad
4
Dodano do listy ... ale nie próbujmy przekształcać jej w wyczerpującą listę wszystkich możliwych prawdziwych wartości! :-)
Zajmie
3

Aby dodać do listy wartości fałszowania @ user568458:

  • Oprócz liczby całkowitej 0 liczba dziesiętna 0,0, 0,00 lub dowolna taka liczba zerowa jest również wartością fałszowania.

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

    Wydruki kodu powyżej I am a falsy value

  • Podobnie reprezentacja szesnastkowa liczby 0 jest również wartością fałszowania, jak pokazano w poniższym fragmencie kodu:

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

    Powyższy fragment kodu ponownie drukuje I am a falsy value.

RBT
źródło
7
JavaScript nie ma liczb całkowitych. 0, 0x0, 0.0I 0.00są to różne literałami dla tego samego IEEE 754 64-bitowych zmiennoprzecinkową wartość zero.
fredoverflow
1

Oprócz tego, od ES2020 mamy nową wartość, która jest fałszem, jest to BigInt zero (0n):

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

Dzięki temu mamy teraz łącznie 7 wartości „falsy” (bez uwzględnienia document.all, jak wspomniano powyżej, ponieważ jest to część DOM, a nie JS).

GetMeARemoteJob
źródło
1
Miły! Dzięki, jeszcze o tym nie słyszałem, dodałem go do dużej listy z linkiem podającym twoją odpowiedź za podniesienie go
user56reinstatemonica8