All falsey values in JavaScript
Asked Answered
Z

4

267

What are the values in JavaScript that are 'falsey', meaning that they evaluate as false in expressions like if(value), value ? and !value?


There are some discussions of the purpose of falsey values on Stack Overflow already, but no exhaustive complete answer listing what all the falsey values are.

I couldn't find any complete list on MDN JavaScript Reference, and I was surprised to find that the top results when looking for a complete, authoritative list of falsey values in JavaScript were blog articles, some of which had obvious omissions (for example, NaN), and none of which had a format like Stack Overflow's where comments or alternative answers could be added to point out quirks, surprises, omissions, mistakes or caveats. So, it seemed to make sense to make one.

Zinfandel answered 7/11, 2013 at 15:34 Comment(7)
Did you check the language spec?Ornithorhynchus
@tibos blog.stackoverflow.com/2011/07/…Zinfandel
dorey.github.io/JavaScript-Equality-Table is a great resource and has an if() tab for truthiness.Ardussi
Wow, really useful, thanks! [[]] == "" but [] != []?My head hurts...Zinfandel
The ECMA 262 Specification details these comparison rules, specifically sec 11.9.1 through 11.9.6: ecma-international.org/ecma-262/5.1/#sec-11.9.3 It would be swell if you updated your answer to include this reference, since it provides the rules for how true/false determinations are (supposed to be) made.Trituration
Likewise, the ECMA-262 specification for "ToBoolean" behavior is well documented: ecma-international.org/ecma-262/5.1/#sec-9.2Trituration
At least nowadays, there's some information on MDN in a different part of the web site than what you searched: (in docs/Glossary/Falsy rather than docs/Web/JavaScript) developer.mozilla.org/en-US/docs/Glossary/FalsyStarch
Z
453

Falsey values in JavaScript

  • false
  • Zero of Number type: 0 and also -0, 0.0, and hex form 0x0 (thanks RBT)
  • Zero of BigInt type: 0n and 0x0n (new in 2020, thanks GetMeARemoteJob)
  • "", '' and `` - strings of length 0
  • null
  • undefined
  • NaN
  • document.all (in HTML browsers only)
    • This is a weird one. document.all is a falsey object, with typeof as undefined. It was a Microsoft-proprietory function in IE before IE11, and was added to the HTML spec as a "willful violation of the JavaScript specification" so that sites written for IE wouldn't break on trying to access, for example, document.all.something; it's falsy because if (document.all) used to be a popular way to detect IE, before conditional comments. See Why is document.all falsy? for details

"Falsey" simply means that JavaScript's internal ToBoolean function returns false. ToBoolean underlies !value, value ? ... : ...; and if (value). Here's its official specification (2020 working draft) (the only changes since the very first ECMAscript specification in 1997 are the addition of ES6's Symbols, which are always truthy, and BigInt, mentioned above:

Argument type Result
Undefined Return false.
Null Return false.
Boolean Return argument.
Number If argument is +0, -0, or NaN, return false; otherwise return true.
String If argument is the empty String (its length is zero), return false; otherwise return true.
BigInt If argument is 0n, return false; otherwise return true.
Symbol Return true.
Object Return true.

Comparisons with == (loose equality)

It's worth talking about falsy values' loose comparisons with ==, which uses ToNumber() and can cause some confusion due to the underlying differences. They effectively form three groups:

  • false, 0, -0, "", '' all match each other with ==
    • e.g. false == "", '' == 0 and therefore 4/2 - 2 == 'some string'.slice(11);
  • null, undefined match with ==
    • e.g. null == undefined but undefined != false
    • It's also worth mentioning that while typeof null returns 'object', null is not an object, this is a longstanding bug/quirk that was not fixed in order to maintain compatibility. It's not a true object, and objects are truthy (except for that "wilful violation" document.all when Javascript is implemented in HTML)
  • NaN doesn't match anything, with == or ===, not even itself
    • e.g. NaN != NaN, NaN !== NaN, NaN != false, NaN != null

With "strict equality" (===), there are no such groupings. Only false === false.

This is one of the reasons why many developers and many style guides (e.g. standardjs) prefer === and almost never use ==.


Truthy values that actually == false

"Truthy" simply means that JavaScript's internal ToBoolean function returns true. A quirk of Javascript to be aware of (and another good reason to prefer === over ==): it is possible for a value to be truthy (ToBoolean returns true), but also == false.

You might think if (value && value == false) alert('Huh?') is a logical impossibility that couldn't happen, but it will, for:

  • "0" and '0' - they're non-empty strings, which are truthy, but Javascript's == matches numbers with equivalent strings (e.g. 42 == "42"). Since 0 == false, if "0" == 0, "0" == false.
  • new Number(0) and new Boolean(false) - they're objects, which are truthy, but == sees their values, which == false.
  • 0 .toExponential(); - an object with a numerical value equivalent to 0
  • Any similar constructions that give you a false-equaling value wrapped in a type that is truthy
  • [], [[]] and [0] (thanks cloudfeet for the JavaScript Equality Table link)

Some more truthy values

These are just a few values that some people might expect to be falsey, but are actually truthy.

  • -1 and all non-zero negative numbers

  • ' ', " ", "false", 'null'... all non-empty strings, including strings that are just whitespace

  • Anything from typeof, which always returns a non-empty string, for example:

  • Any object (except that "wilful violation" document.all in browsers). Remember that null isn't really an object, despite typeof suggesting otherwise. Examples:

    • {}
    • []
    • function(){} or () => {} (any function, including empty functions)
    • Error and any instance of Error
    • Any regular expression
    • Anything created with new (including new Number(0) and new Boolean(false))
  • Any Symbol

true, 1, "1" and [1] return true when compared to each other with ==.

Zinfandel answered 7/11, 2013 at 15:34 Comment(10)
FYI, what !, if and ?..: have in common is that they call the internal ToBoolean function on the value. How those values behave in the context of !, if, etc. is already implied by their name: They are "falsy" values. I'm a bit afraid that others will read the answer and think "Oh so in this context (!, if, ?...:), the value is false, but with !!, it's true", but don't understand the underlying concept. Two other points: 1) v ? true : false is just a verbose way of !!v. 2) typeof always returns a non-empty string, which is truthy.Pinhead
I.e. there is no point in looking at typeof null or typeof undefined specifically. You could just say that non-empty strings are truthy.Pinhead
I see, but this has nothing to do with the original question ;) Adding too much somewhat related but not relevant information could be rather confusing for readers.Pinhead
I have just learned that document.all is falsy as well.Definitely
Regarding loose comparison: because Booleans are converted to numbers, x == false will call ToNumber(x) which is just very different from ToBoolean(x). Might be worth explaining. Also I just noticed that I already commented on this answer ages ago :DPinhead
Is there a reason to consider '' and "" to be separate values?Seoul
"" and '' are alternative notations for the same value. They should be in the same bullet. And if you're going to do that, you may as well include void 0 next to undefined.Teston
It's questionable whether document.all should be included in this list. This question is about JavaScript, not HTML.Teston
@Teston that's why I say "This is a weird one" and that it was "added to the HTML spec as a 'willful violation of the JavaScript specification'"...Zinfandel
Why are 0x0 and 0x0n specially mentioned, but not 0b0 or 0o0 or 0e0, etc.?Earsplitting
D
4

Just to add to @user568458's list of falsy values:

  • In addition to integer number 0, the decimal number 0.0, 0.00 or any such zeroish number is also a falsy value.

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

    Above code snippet prints I am a falsy value

  • Similarly hex representation of the number 0 is also a falsy value as shown in below code snippet:

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

    Above code snippet again prints I am a falsy value.

Distinguishing answered 20/9, 2017 at 0:10 Comment(1)
JavaScript does not have integer numbers. 0, 0x0, 0.0 and 0.00 are just different literals for the same IEEE-754 64-bit floating point value zero.Stockmon
W
4

Don't forget about the non-empty string "false" which evaluates to true

Wrung answered 4/10, 2017 at 1:16 Comment(3)
…and is therefore not a falsy value, which was asked for?Villose
touché. it's a value you might expect to be falsey and isn't, which is still worth being aware of, and I think, merits mention on a comprehensive listWrung
Added to the list... but let's not try to turn this into a comprehensive list of all possible truthy values! That'd take a while :-)Zinfandel
C
2

Addition to the topic, as of ES2020 we have a new value which is falsy, it's BigInt zero (0n):

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

So with this, we now have 7 "falsy" values in total (not including document.all as mentioned by user above since it's part of DOM and not JS).

Clougher answered 1/5, 2020 at 22:15 Comment(1)
Nice! Thanks, I hadn't heard about that yet, I've added it to the big list with a link crediting your answer for raising itZinfandel

© 2022 - 2024 — McMap. All rights reserved.