Related
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.
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:
typeof null (returns a string 'object' due to a longstanding bug/quirk)
typeof undefined (returns a string 'undefined')
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 ==.
Don't forget about the non-empty string "false" which evaluates to true
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.
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).
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.
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:
typeof null (returns a string 'object' due to a longstanding bug/quirk)
typeof undefined (returns a string 'undefined')
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 ==.
Don't forget about the non-empty string "false" which evaluates to true
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.
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).
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.
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:
typeof null (returns a string 'object' due to a longstanding bug/quirk)
typeof undefined (returns a string 'undefined')
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 ==.
Don't forget about the non-empty string "false" which evaluates to true
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.
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).
When I compare undefined and null against Boolean false, the statement returns false:
undefined == false;
null == false;
It return false. Why?
With the original answer pointing to the spec being deleted, I'd like to provide a link and short excerpt from the spec here.
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3
The ECMA spec doc lists the reason that undefined == false returns false. Although it does not directly say why this is so, the most important part in answering this question lies in this sentence:
The comparison x == y, where x and y are values, produces true or false.
If we look up the definition for null, we find something like this:
NULL or nil means "no value" or "not applicable".
In Javascript, undefined is treated the same way. It is without any value. However, false does have a value. It is telling us that something is not so. Whereas undefined and null are not supposed to be giving any value to us. Likewise, there is nothing it can convert to for its abstract equality comparison therefore the result would always be false. It is also why null == undefined returns true (They are both without any value). It should be noted though that null === undefined returns false because of their different types. (Use typeof(null) and typeof(undefined) in a console to check it out)
What I'm curious of though, is that comparing NaN with anything at all will always return false. Even when comparing it to itself. [NaN == NaN returns false]
Also, another odd piece of information: [typeof NaN returns "number"]
Strict Equality
If possible, you should avoid using the == operator to compare two values. Instead use === to truly see if two values are equal to each other. == gives the illusion that two values really are exactly equal when they may not be by using coercion. Examples:
5 == "5" is true
5 === "5" is false
"" == false is true
"" === false is false
0 == false is true
0 === false is false
From the incomparable MDN, sponsored by the company of JavaScript's creator.
JavaScript provides three different value-comparison operations:
strict equality (or "triple equals" or "identity") using ===,
loose equality ("double equals") using ==,
and Object.is (new in ECMAScript > 6).
The choice of which operation to use depends on what sort of
comparison you are looking to perform.
Briefly, double equals will perform a type conversion when comparing
two things; triple equals
will do the same comparison without type conversion (by simply always
returning false if the types differ); and Object.is will behave the
same way as triple equals, but with special handling for NaN and -0
and +0 so that the last two are not said to be the same, while
Object.is(NaN, NaN) will be true. (Comparing NaN with NaN
ordinarily—i.e., using either double equals or triple equals—evaluates
to false, because IEEE 754 says so.) Do note that the distinction
between these all have to do with their handling of primitives; none
of them compares whether the parameters are conceptually similar in
structure. For any non-primitive objects x and y which have the same
structure but are distinct objects themselves, all of the above forms
will evaluate to false.
For a visual overview of the whole picture of equality in JavaScript:
https://dorey.github.io/JavaScript-Equality-Table/
The truth is, this seemingly "bad" aspect of JavaScript is a source of power when you understand how it works.
So undefined really means undefined. Not False, not True, not 0, not empty string. So when you compare undefined to anything, the result is always false, it is not equal to that.
You question is half, as we compare undefined/ null to any other types.
we will have false return.
There is no coercion happening, even we are using == operator.
This is so because it is so. :)
Read the ECMA standards here: https://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3
Undefined is not the same thing as false, false is a boolean object (which has a value of 0 therefore it is indeed defined).
An example:
var my_var;
var defined = (my_var === undefined)
alert(defined); //prints true. It is true that my_var is undefined
my_var = 22;
defined = (my_var === undefined)
alert(defined); //prints false. my_var is now defined
defined = (false === undefined)
alert(defined); //prints false, false is defined
defined = (true === undefined)
alert(defined); //prints false, true is defined
According to the specification flow:
If Type(y) is Boolean, return the result of the comparison x ==
ToNumber(y).
1) undefined == false; -> undefined == Number(false); -> undefined == 0;
2) null == false; -> null == Number(false); -> null == 0;
There is no rule for these cases, so go with the behavior in the last step:
Return false.
I had an interesting interview question today that stumped me a little. I was asked about falsey values. So undefined, NaN, null, 0, and an empty string all evaluate to false. What is the reason this is useful to know in JavaScript? The only thing I can think of is instead of having to do this:
if (mystring === '' || mystring === undefined) { }
I can do this:
if (!mystring)
Is this the only useful application?
One dangerous issue of falsey values you have to be aware of is when checking the presence of a certain property.
Suppose you want to test for the availability of a new property; when this property can actually have a value of 0 or "", you can't simply check for its availability using
if (!someObject.someProperty)
/* incorrectly assume that someProperty is unavailable */
In this case, you must check for it being really present or not:
if (typeof someObject.someProperty == "undefined")
/* now it's really not available */
Also be aware that NaN isn't equal to anything, even not to itself (NaN != NaN).
There are two separate issues with 'falsey' values in JavaScript.
Firstly there is the official conversion scheme, which is what is returned by Boolean(x). This returns false when x is false or 0 or NaN or null or undefined or "" and true otherwise. This is the same behaviour as the
if (condition) {/*true path*/} else {/*false path*/}
that is, the false path is executed if Boolean(condition) would have returned false and the true path is executed otherwise. This behaviour is often used to check to see if a property is defined. However, doing that is not safe unless you are certain that the property would be an object or an array if it is defined. The safest way to test if a property is defined is to do
if (property != null) { /*property is defined*/}
which makes sure that the property is not null or undefined. If you only want to make sure the property is not undefined do
if (property !== undefined) { /*property is not undefined (but may be null)*/ }
(notice the extra = in !==).
Secondly, there are all the values that == false. This is everything that can be coerced to 0 (which is what false gets coerced to). This includes all the values that convert to false except NaN (which can't == false by virtue of it never == anything), null and undefined. But it also includes all objects that when converted to a string and then converted to a number are equal to 0. For example, this includes everything that when converted to a string is either the empty string "" or "0" or "-0" or "+0" or "0x00" or "000" or "0e0" or "0.0000"...., for example,
({toString: function() {return "-00.0e000";}}) == false
is true. Interestingly, this includes the empty array, and any nesting of arrays containing only a single other item that returns an empty or 0 string since arrays rendered as strings show only the contents without the surrounding brackets. That is,
[[[[0]]]] == false; // Because [[[[0]]]].toString() === "0"
[] == false;
[[[""]]] == false;
["0"] == false;
[[({toString: function() {return "0";}})]] == false;
The full algorithm for calculating == false is described here.
The reason this matters is because it can lead to subtle, difficult to find bugs if you don't understand most of these rules. Most important takeaways are probably how the if (condition) works and that using === avoids most of the other crazy stuff.
It's important to understand how this works in JS, so you're not surprised. Not necessarily just what is falsey, but what is truthy and how they compare to each other.
One example is that '0' is considered equal to 0 with ==, but it is not equal to '' - though 0 is. JavaScript comparison isn't always transitive.
So this means that just because (foo==bar && bar==fizz) is true, (foo==fizz) is not always true. To go with the above example, '0'==0, and 0=='', but '0'!='' - because you're comparing strings in the latter instance, so they are compared as strings and not coerced to numbers.
It is important to know that 0 evaluates to false to prevent doing things like:
if(str.indexOf('foo'))
It's useful to detect if a browser is has specific predefined objects:
if(!!navigator.geolocation){
// executes if the browser has geolocation support
}
if(!!document.createElement('canvas').getContext){
// executes if the browser supports <canvas>
}
Explanation: navigator.geolocation is an object or undefined. In the case it's an object !navigator.geolocation will return false, if it's undefined it'll return true. So, to check if a browser has geolocation enabled, you want to 'flip' the boolean once more, by adding another !.
They're also useful for setting default values...
function foo(bar){
alert(bar || "default");
}
I know a lot of people try to do
if (typeof(foo) === "undefined"){}
to get around falsiness, but that's got its own problems because
typeof(null) === "object"
for some reason