Booleans & truthiness
Learn true and false, compare values, convert truthy and falsy inputs, avoid == true traps, and use booleans in practical JavaScript.
- 01Read boolean answersKnow the two booleans,
trueandfalse, and spot the booleans that comparisons, yes/no methods, and!give you. - 02Predict truthy and falsyUse the list of eight falsy values. Explain why values like
"false",[], andnew Boolean(false)are truthy. - 03Write safer checksTurn values into booleans on purpose, avoid
== true, and pick the right check for toggles, lists, forms, and text from web addresses.
Watch the video lecture
Full course on YouTube (opens in a new tab) ↗- Lecture 16Booleans, truthy, and falsyWatch on YouTube (opens in a new tab) ↗
true and false
A boolean is a yes/no value. There are only two booleans: true means yes, and false means no. Booleans are primitive values: simple values, like numbers and strings.
You will often keep booleans in variables with names like isOpen, hasItems, isLoggedIn, and checked.
const isOpen = true;const hasItems = false;console.log(typeof true);console.log(isOpen);console.log(hasItems);Line 1 stores true in isOpen. Line 2 stores false in hasItems. Line 3 uses typeof, which gives the type of a value as text. It prints "boolean", because true is a boolean, not a string. Lines 4 and 5 print the two stored values.
You can give these variables any name. But names that start with is, has, or can read like yes/no questions, so the code is easy to read.
A boolean is exactly true or false. Any other value can stand in for a boolean when JavaScript needs a yes/no answer, for example in an if. A value is truthy when JavaScript treats it like true. A value is falsy when JavaScript treats it like false. Whether a value is truthy or falsy is called its truthiness.
A guard stands at a party door. The guard has a short list of names that may not come in. If your name is on that list, the answer is no. Everyone else comes in. The guard only checks the list. It does not matter what else is written on your name tag.
- In real life: The few names on the no list
- In JavaScript: The eight falsy values
- In real life: Everyone else comes in
- In JavaScript: Every other value is truthy
- In real life: A name tag that says No still gets in
- In JavaScript: The string
"false"is truthy
This lesson is about using booleans. To see how the engine stores them, read Booleans inside the engine. Later, the Booleans, null & undefined lesson puts booleans next to null and undefined, the two values that mean "nothing here".
Where booleans come from
STEP THROUGHYou can write true and false yourself. But most booleans come from questions that your code asks:
- A comparison, such as
5 > 3, asks how two values compare. - Some methods ask a yes/no question, such as "does this text contain
ell?" - The not operator,
!, gives the opposite answer.
Step through the places where booleans come from: values you write, comparisons, yes/no methods, and !.
script
const hasItems = false;const trueType = typeof true;const bigger = 5 > 3;const sameLetter = "a" === "A";const hasEll = "hello".includes("ell");const isArray = Array.isArray([]);const isReallyNaN = Number.isNaN(NaN);const startsWithC = "cat".startsWith("c");const isClosed = !isOpen;console.log(isOpen, hasItems, trueType);console.log(bigger, sameLetter);console.log(hasEll, isArray, isReallyNaN, startsWithC);console.log(isClosed);Read each variable name as a question:
biggerasks: is 5 more than 3? Yes, so it holdstrue.sameLetterasks: is"a"the same as"A"? No, because small and capital letters are different. So it holdsfalse.hasEllasks: does"hello"contain"ell"? Yes.isArrayasks: is[]an array? Yes.isReallyNaNasks: is this valueNaN, the "not a number" value? Yes.startsWithCasks: does"cat"start with"c"? Yes.isCloseduses!to get the opposite ofisOpen.isOpenistrue, soisClosedisfalse.
true for yes, false for no.Turning a value into a boolean
STEP THROUGHSometimes you have a value and want to know: will JavaScript treat it as true or as false? Finding out is called boolean conversion. There are two common ways to get the answer:
Boolean(value)gives the answer astrueorfalse. This is the clearest way.!!valuegives the same answer. It uses the not operator!two times.
Compare Boolean(value), !!value, !value, and the block that if (value) runs.
script
const explicit = Boolean(value);const compact = !!value;const flipped = !value;if (value) { console.log("truthy branch");} else { console.log("falsy branch");}console.log(explicit, compact, flipped);An if (value) does the same conversion to choose which block of code to run. None of these change value itself. They only answer a yes/no question about it.
Why does !! work? One ! gives the opposite answer. A second ! gives the opposite of that, which is the plain answer again.
! gives the opposite, true. The second ! flips it back to false. So !!value gives the same answer as Boolean(value).The eight falsy values
Only eight values are falsy. Learn this list by heart. Every other value is truthy.
false0-00n""nullundefinedNaN
Browsers have one old object, document.all, that is falsy even though it is an object. Browsers keep this rule only so that very old web pages still work. The rule is in a part of the specification called Annex B, under the name [[IsHTMLDDA]]. You will not need it in your own code. If you are curious, Null inside the engine explains it.
The surprises are all on the truthy side. These values look empty or false, but they are truthy:
- The strings
"0","false", and" "(one space). - An empty array,
[], and an empty object,{}. - Functions and symbols.
- Wrapper objects, such as
new Boolean(false). You'll meet them later in this lesson.
The quotes matter. "0" and "false" are strings with characters in them, so they are not empty. [] and {} are objects, and objects are truthy. JavaScript does not read the words inside a string. So Boolean("0"), Boolean("false"), Boolean([]), and Boolean({}) all give true.
Truthiness playground
48 VALUESPick a value from the list and see how JavaScript treats it. The playground shows three results: Boolean(value), !!value, and which block if (value) runs.
The last group, "Computed expressions", holds common bugs. For example, "abc".indexOf("a") gives 0, because "a" is at position 0, and 0 is falsy. And 0.1 + 0.2 - 0.3 leaves a tiny number that is not quite zero, so it is truthy.
const value = "0";console.log(Boolean(value));console.log(!!value);if (value) { console.log("truthy branch");} else { console.log("falsy branch");}A string with characters in it is truthy, even when the character is 0.
"0" is truthy. Boolean(value) is true, !!value is true, and if (value) runs the truthy branch. A string with characters in it is truthy, even when the character is 0.
false0-00n""nullundefinedNaN"0""false"" "[]{}[""][[]]function () {}Symbol()1n-1Infinitynew Boolean(false)new Number(0)new String("")/(?:)/
Put each card in the right group. Watch out: empty arrays, empty objects, and wrapper objects are truthy.
The table below lists every value from the playground, in the same groups. Read each row as: this value is truthy or falsy, and here is why. The middle column is worked out from the real value when the page is built, so it is always right.
| The value | Truthy or falsy? | Why |
|---|---|---|
true | truthy | true is already a boolean, so it stays true. |
false | falsy | The boolean false is falsy by definition. |
null | falsy | null means "empty on purpose". It is on the falsy list. |
undefined | falsy | undefined means "no value was given". It is on the falsy list. |
void 0 | falsy | The void operator always gives undefined, so this is falsy too. |
"" | falsy | Only the string with zero characters is falsy. |
"0" | truthy | A string with characters in it is truthy, even when the character is 0. |
"false" | truthy | JavaScript does not read the word inside the string. The string is not empty, so it is truthy. |
" " | truthy | A space is a character, so the string is not empty. |
"\n" | truthy | A new line counts as one character, so the string is not empty. |
"null" | truthy | This is text, not the value null. The text is not empty, so it is truthy. |
"undefined" | truthy | This is text that spells undefined. The text is not empty, so it is truthy. |
"NaN" | truthy | This is text, not the number value NaN. The text is not empty, so it is truthy. |
0 | falsy | Number zero is falsy. |
-0 | falsy | Negative zero is still zero for truthiness. |
NaN | falsy | NaN means "not a number". It is on the falsy list. |
-1 | truthy | Any number that is not zero is truthy, even a negative one. |
0.1 | truthy | Any decimal number that is not zero is truthy. |
Infinity | truthy | Infinity is a number that is not zero, so it is truthy. |
-Infinity | truthy | -Infinity is a number that is not zero, so it is truthy. |
0n | falsy | 0n is zero as a BigInt, a number type for very big whole numbers. It is falsy. |
1n | truthy | A BigInt that is not zero is truthy. |
-1n | truthy | A negative BigInt is not zero, so it is truthy. |
[] | truthy | An array is an object, and objects are truthy. |
({}) | truthy | An object is truthy, even when it holds nothing. |
[0] | truthy | The array is truthy, even though the item inside it is falsy. |
[""] | truthy | The array is an object, so it is truthy. The falsy item inside does not matter. |
[[]] | truthy | This is an array with an empty array inside. The outer array is an object, so it is truthy. |
function () {} | truthy | A function is an object, and objects are truthy. |
() => {} | truthy | An arrow function is a function, so it is truthy. |
Symbol() | truthy | Every symbol is truthy. |
new Date(0) | truthy | A date is an object, so it is truthy. |
/(?:)/ | truthy | A regular expression, a pattern for searching text, is an object. So it is truthy. |
new Boolean(false) | truthy | This makes an object with false inside. The object is truthy. |
new Number(0) | truthy | This makes an object with 0 inside. The object is truthy. |
new String("") | truthy | This makes an object with an empty string inside. The object is truthy. |
"abc".indexOf("a") | falsy | "a" is at position 0, so indexOf gives 0, which is falsy. This is a common indexOf bug. |
"".length | falsy | The empty string has 0 characters, and 0 is falsy. |
Number("") | falsy | Converting an empty string to a number gives 0, which is falsy. |
Number("abc") | falsy | "abc" is not a number, so Number gives NaN, which is falsy. |
parseInt("px") | falsy | parseInt reads digits from the start of the text. "px" has none, so it gives NaN, which is falsy. |
1e-400 | falsy | This number is too tiny for JavaScript to store, so it becomes 0, which is falsy. |
0 * -1 | falsy | The calculation creates -0, and -0 is falsy. |
[].length | falsy | An empty array is truthy, but its length is the falsy number 0. |
" ".trim() | falsy | trim() removes spaces from both ends. Only spaces were there, so it gives the empty string, which is falsy. |
[1, 2].find((n) => n > 5) | falsy | No number is bigger than 5, so find finds nothing and gives undefined, which is falsy. |
5 - 5 | falsy | 5 - 5 is 0, and 0 is falsy. |
0.1 + 0.2 - 0.3 | truthy | Computers store 0.1 and 0.2 a tiny bit off. So the result is a tiny number, not exactly 0, and it is truthy. |
Booleans in conditions and logic
An if uses truthiness to decide whether to run its block. The operators work like this:
!(not) always gives a real boolean:trueorfalse.||(or) and&&(and) are different. They don't always give a boolean. They give back one of the two values you gave them.
This is only a first look. The Logical operators lesson covers them in full.
const name = "";const fallback = name || "friend";const subscribed = true;const access = subscribed && "member area";console.log(fallback);console.log(access);console.log(!subscribed);- Line 2:
nameis the empty string, which is falsy. So||gives back the other value,"friend". - Line 4:
subscribedistrue, so&&gives back the second value, the string"member area". It does not give the booleantrue. - Line 7 uses
!, so it prints a real boolean:false.
Two traps: Boolean objects and == true
TRAPSBoolean(x) without new gives a plain boolean. new Boolean(false) is different. It makes an object with false inside it. An object like this is called a wrapper object. Every object is truthy, so this object is truthy too. That makes it dangerous in an if.
const boxed = new Boolean(false);console.log(Boolean(boxed));console.log(typeof boxed);console.log(boxed.valueOf());console.log(Boolean(false));- Line 1 makes the wrapper object and stores it in
boxed. - Line 2 prints
true, because the object is truthy. - Line 3 prints
"object", the type ofboxed. - Line 4 uses
valueOf(), a method that takes out the value inside. It printsfalse. - Line 5 converts the plain value
false, so it printsfalse.
false. On the right, new Boolean(false) makes an object and puts false inside it. JavaScript checks the object, not what is inside, and every object is truthy.When you need a boolean, write true, false, Boolean(value), or a comparison. Don't write new Boolean(...). The same goes for new Number(...) and new String(...): they make objects, not plain values.
The second trap is writing == true or == false. The == operator is called loose equality: it changes the values before it compares them. When one side is a boolean, it turns that boolean into a number: true becomes 1 and false becomes 0. Then it turns the other side into a number too. That gives surprising results.
console.log("1" == true);console.log("true" == true);console.log([] == false);console.log(Boolean([]));- Line 1:
"1"becomes 1 andtruebecomes 1, so it printstrue. - Line 2:
"true"is not a number, so it becomesNaN.NaNis not equal to 1, so it printsfalse. - Line 3:
[]becomes the empty string, then 0.falsealso becomes 0, so it printstrue. - Line 4 shows that
[]is still truthy. So== falseand "is it falsy?" are different questions.
The table asks three questions about each value. Read each row from left to right.
| The value | Truthy? Boolean(value) | value == true | value == false |
|---|---|---|---|
"1" | true | true | false |
"true" | true | false | false |
[] | true | false | true |
0 | false | false | true |
"false" | true | false | false |
Write if (value) when you mean "is it truthy?". Write value === true when it must be the boolean true and nothing else. The === operator is strict equality: it never changes the values before it compares them.
Booleans in real code
Real code uses booleans in many places. Each place asks a different yes/no question.
Name boolean variables like questions: isOpen, hasItems, and isLoggedIn. Then if (isOpen) reads like plain English: "if it is open". Each variable should answer one clear question.
- Toggles, which switch between on and off: flip a boolean with
isOpen = !isOpen. - Form controls: a checkbox has a
.checkedproperty. It istruewhen the box is ticked. - Arrays:
if (items.length)asks whether the list has any items. A length of0is falsy. - Cleanup:
array.filter(Boolean)keeps only the truthy values. It also removes0andfalse. - Text from web addresses or forms: it arrives as the string
"true"or"false". Compare the exact text.
let isOpen = false;isOpen = !isOpen;console.log(isOpen);const checkbox = { checked: true };console.log(checkbox.checked);const cart = [];const hasItems = cart.length > 0;const user = { name: "Asha" };const isLoggedIn = Boolean(user);console.log(hasItems, isLoggedIn);- Line 1: the toggle starts as
false, which means closed. - Line 2:
!isOpengives the opposite, soisOpenbecomestrue. Line 3 printstrue. - Line 5 prints the checkbox's
checkedproperty,true. - Line 7: the cart is empty, so its length is 0 and
hasItemsisfalse. - Line 9:
useris an object, soBoolean(user)istrue. - Line 10 prints
false true.
const items = ["hat", "coat"];if (items.length) { console.log("show cart");}const mixed = [0, 1, "", "Ada", null, false, true];console.log(mixed.filter(Boolean).join("|"));- Line 2: the list has 2 items. 2 is truthy, so line 3 prints
show cart. - Line 6:
filter(Boolean)keeps only the truthy values. It removes0,"",null, andfalse. Thenjoin("|")puts the kept values into one string with|between them, so it prints1|Ada|true.
const fromUrl = "false";console.log(Boolean(fromUrl));console.log(fromUrl === "true");console.log(fromUrl === "false" ? false : fromUrl === "true");- Line 1: text from a web address is always a string. Here it is
"false". - Line 2 prints
true, because the string is not empty. SoBoolean()can't read this text for you. - Line 3 compares the exact text and prints
false. - Line 4 uses
? :, a short if/else. If the text is"false", the answer isfalse. If not, the answer is whether the text is"true". Here it printsfalse.
Common misconceptions
- "The string
"false"is false." It is a string with characters in it, so it is truthy. - "A string of spaces is empty."
" "and"\n"(a new line) contain characters, so they are truthy. - "Empty arrays and objects are falsy." They are objects, and objects are truthy.
- "
new Boolean(false)works likefalse." It is an object, so it is truthy. - "
== truechecks truthiness." It turns both sides into numbers first, so it can give surprising answers. - "
filter(Boolean)only removes missing values." It removes every falsy value, including0andfalse. - "
if (value)only checks for a missing value." It also skipsfalse,0,"", andNaN.
Practice exercises
6 EXERCISESWhat do the four lines print? Write them in order.
console.log(typeof true);
console.log(5 > 3);
console.log("a" === "A");
console.log(!"hello".includes("z"));The outputs are boolean, true, false, and true. Comparisons and ! give plain booleans.
How many values are on the falsy list?
const falsy = [false, 0, -0, 0n, "", null, undefined, NaN];
console.log(falsy.length);
console.log(falsy.every((value) => !value));The list holds 8 values, and every one is falsy. So the outputs are 8 and true.
A web address gave you the string "false". What does the exact comparison on line 3 print?
const raw = "false";
console.log(Boolean(raw));
console.log(raw === "true");const raw = "false";
console.log(Boolean(raw));
console.log(raw === "true");raw is the string "false", so raw === "true" prints false. The string itself is truthy, so Boolean(raw) can't read the text for you.
What does line 2 print?
const values = [0, 1, 2, "", "ok", null, false, true];
console.log(values.filter(Boolean).join("|"));The kept values print as 1|2|ok|true. If 0 or false is real data that you need, write your own test inside filter instead.
The code prints missed, but "a" is in the string. Why?
const position = "abc".indexOf("a");
if (position) {
console.log("found");
} else {
console.log("missed");
}indexOf gave 0, the position of "a". 0 is falsy, so if (position) ran the else block. indexOf gives -1 only when it finds nothing, so check position !== -1 instead, or use includes.
What do the three lines print?
const boxed = new Boolean(false);
console.log(Boolean(boxed));
console.log(typeof boxed);
console.log(Boolean(false));The object is truthy, and its type is object. The plain false stays falsy. The outputs are true, object, false.
Check your understanding
8 QUESTIONSQuestion 1 of 8How many boolean values does JavaScript have?
Choose an answer to see the explanation.
Question 2 of 8What do the comparison and method print?
Read the code, then predictconsole.log(5 > 3); console.log("hello".includes("z"));Choose an answer to see the explanation.
Question 3 of 8What does this print?
Read the code, then predictconsole.log(Boolean("false"));Choose an answer to see the explanation.
Question 4 of 8What do the empty and space strings print?
Read the code, then predictconsole.log(Boolean("")); console.log(Boolean(" "));Choose an answer to see the explanation.
Question 5 of 8What does this array check print?
Read the code, then predictconsole.log(Boolean([])); console.log([].length === 0);Choose an answer to see the explanation.
Question 6 of 8What do these loose equality checks print?
Read the code, then predictconsole.log("1" == true); console.log("true" == true);Choose an answer to see the explanation.
Question 7 of 8What does a Boolean object do?
Read the code, then predictconst value = new Boolean(false); console.log(Boolean(value)); console.log(typeof value);Choose an answer to see the explanation.
Question 8 of 8What does this tiny number print?
Read the code, then predictconsole.log(Boolean(0.1 + 0.2 - 0.3));Choose an answer to see the explanation.
Key takeaways
- There are exactly two booleans:
trueandfalse. - Comparisons, yes/no methods, and
!give booleans. - The eight falsy values are
false,0,-0,0n,"",null,undefined, andNaN. - Every other value is truthy. That includes
"false",[],{}, andnew Boolean(false). - Don't write
== true. Useif (value)to check truthiness, orvalue === trueto check for the booleantrue. - In real code, pick the check that fits the question:
items.lengthfor "any items?",filter(Boolean)to drop falsy values, andraw === "true"to read text.
Final definition: a boolean is the yes/no value true or false. Truthiness is how JavaScript reads any other value as true or false when it needs a yes/no answer.
Up next: undefined, the value JavaScript uses when nothing has been given yet.