What are Truthy and Falsy Values in JavaScript?
Learn what truthy and falsy values are in JavaScript. Covers the 8 falsy values, truthy surprises like empty arrays and zero-strings, Boolean coercion, double negation, and common conditional pitfalls.
Every value in JavaScript is either truthy or falsy. When JavaScript needs a boolean (in an if statement, a ternary, a logical operator), it converts the value to true or false automatically. This conversion is called boolean coercion, and understanding it is essential for writing correct conditionals, avoiding hidden bugs, and working with logical operators.
There are exactly 8 falsy values in JavaScript. Everything else is truthy. This tutorial covers all 8 falsy values, the surprising truthy values that trip people up, how Boolean() and double negation work, and practical patterns for safe condition checking.
The 8 Falsy Values
These are the only values that coerce to false:
| Value | Type | Description |
|---|---|---|
false | Boolean | The boolean false itself |
0 | Number | The number zero |
-0 | Number | Negative zero |
0n | BigInt | BigInt zero |
"" | String | Empty string (no characters) |
null | Object* | Intentional absence of value |
undefined | Undefined | Variable declared but not assigned |
NaN | Number | Not a Number (result of invalid math) |
if (false) console.log("won't run");
if (0) console.log("won't run");
if (-0) console.log("won't run");
if (0n) console.log("won't run");
if ("") console.log("won't run");
if (null) console.log("won't run");
if (undefined) console.log("won't run");
if (NaN) console.log("won't run");
console.log("None of the above printed");Only 8 Falsy Values
Memorize these 8 values. Every other value in JavaScript is truthy. When you are uncertain whether a value is truthy or falsy, check it against this list. If it is not one of the 8, it is truthy.
Truthy Values (Everything Else)
Any value not in the falsy list is truthy. Some of these surprise beginners:
// All truthy - these all print
if (true) console.log("boolean true");
if (1) console.log("number 1");
if (-1) console.log("negative numbers are truthy");
if (3.14) console.log("decimals are truthy");
if ("hello") console.log("non-empty strings");
if (" ") console.log("space string is truthy");
if ("0") console.log("string zero is truthy!");
if ("false") console.log("string 'false' is truthy!");
if ([]) console.log("empty array is truthy!");
if ({}) console.log("empty object is truthy!");
if (function(){}) console.log("functions are truthy");
if (new Date()) console.log("Date objects are truthy");
if (Infinity) console.log("Infinity is truthy");
if (-Infinity) console.log("-Infinity is truthy");Commonly Surprising Truthy Values
| Value | Why it surprises | Why it is truthy |
|---|---|---|
"0" | Looks like zero | It is a string with one character, not the number 0 |
"false" | Looks like false | It is a string with content, not the boolean false |
[] | Empty array, seems "nothing" | Arrays are objects; all objects are truthy |
{} | Empty object, seems "nothing" | Objects are always truthy, regardless of properties |
new Boolean(false) | Contains false | It is an object wrapper, and objects are truthy |
" " | Looks empty | Contains a space character; not an empty string |
Boolean Coercion: How JavaScript Converts Values
The Boolean() Function
Boolean() converts any value to its truthy/falsy boolean equivalent:
console.log(Boolean(1)); // true
console.log(Boolean(0)); // false
console.log(Boolean("hello")); // true
console.log(Boolean("")); // false
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean([])); // true
console.log(Boolean({})); // trueDouble NOT (!!) Operator
The double NOT operator is a shorthand for Boolean():
console.log(!!1); // true
console.log(!!0); // false
console.log(!!"hello"); // true
console.log(!!""); // false
console.log(!!null); // false
console.log(!!undefined); // false
console.log(!!NaN); // false
console.log(!![]); // trueHow it works:
- The first
!converts the value to a boolean and flips it - The second
!flips it back to the correct boolean representation
const value = "hello";
// Step 1: !value => !("hello") => false
// Step 2: !!value => !(false) => trueTruthy/Falsy in Conditionals
if Statements
const username = getUserInput();
// Checks if username is truthy (not empty, null, or undefined)
if (username) {
console.log(`Welcome, ${username}`);
} else {
console.log("Please enter a username");
}Ternary Operator
const score = 0;
const message = score ? `Score: ${score}` : "No score yet";
console.log(message); // "No score yet" (0 is falsy!)Zero Is Falsy
The value 0 is a valid score, count, or index. But if (score) treats 0 as falsy. If 0 is a legitimate value in your code, use an explicit comparison: if (score !== undefined) or if (score !== null).
Logical AND (&&) for Guard Checks
const user = getUser();
// Only accesses .name if user is truthy
const name = user && user.name;
console.log(name);Logical OR (||) for Defaults
const input = "";
const value = input || "default";
console.log(value); // "default" (empty string is falsy)Common Pitfalls
Pitfall 1: Empty Array Is Truthy
const items = [];
// Bug: this always runs because [] is truthy
if (items) {
console.log("Has items"); // prints even when array is empty!
}
// Fix: check the length
if (items.length > 0) {
console.log("Has items");
}
// Also valid: check length truthiness (0 is falsy)
if (items.length) {
console.log("Has items");
}Pitfall 2: Zero Is a Valid Value
function displayCount(count) {
// Bug: skips the message when count is 0
if (count) {
console.log(`Count: ${count}`);
} else {
console.log("No count provided");
}
}
displayCount(0); // "No count provided" - wrong!
// Fix: explicit null/undefined check
function displayCount(count) {
if (count !== null && count !== undefined) {
console.log(`Count: ${count}`);
} else {
console.log("No count provided");
}
}
displayCount(0); // "Count: 0" - correct!Pitfall 3: String "0" Is Truthy
const input = "0"; // from a form field
// Bug: "0" is truthy, so this runs
if (input) {
const num = Number(input);
console.log(num); // 0
}
// This is actually fine here. But be careful with:
if (input === "0") {
// explicitly handle "0"
}Pitfall 4: Logical OR (||) Replaces All Falsy Values
function greet(name) {
const displayName = name || "Guest";
return `Hello, ${displayName}`;
}
greet(""); // "Hello, Guest" - empty string is falsy
greet(0); // "Hello, Guest" - zero is falsy
greet(null); // "Hello, Guest" - intended behavior
// Fix: use nullish coalescing (??) to replace only null/undefined
function greet(name) {
const displayName = name ?? "Guest";
return `Hello, ${displayName}`;
}
greet(""); // "Hello, " - empty string is preserved
greet(0); // "Hello, 0" - zero is preserved
greet(null); // "Hello, Guest" - null is replacedPractical Patterns
Safe Property Access
const config = getConfig();
// Relies on truthy check to avoid accessing properties of null/undefined
const theme = config && config.ui && config.ui.theme;
// Modern alternative: optional chaining
const theme = config?.ui?.theme;Filtering Falsy Values from an Array
const mixed = [0, 1, "", "hello", null, undefined, false, true, NaN, 42];
const truthyOnly = mixed.filter(Boolean);
console.log(truthyOnly); // [1, "hello", true, 42]Boolean as a callback works because filter passes each element to the function, and Boolean() returns true for truthy values and false for falsy ones.
Counting Truthy Values
const responses = [true, false, null, "yes", 0, 1, undefined, ""];
const truthyCount = responses.filter(Boolean).length;
console.log(truthyCount); // 3 (true, "yes", 1)Input Validation
function validateForm(fields) {
const errors = [];
if (!fields.email) {
errors.push("Email is required");
}
if (!fields.password) {
errors.push("Password is required");
}
// Check minimum length only if password exists
if (fields.password && fields.password.length < 8) {
errors.push("Password must be at least 8 characters");
}
return errors;
}Comparison Table: Falsy Values in Different Contexts
const values = [false, 0, -0, 0n, "", null, undefined, NaN];| Value | if (val) | val == false | val === false | !val | Boolean(val) |
|---|---|---|---|---|---|
false | no | yes | yes | true | false |
0 | no | yes | no | true | false |
-0 | no | yes | no | true | false |
0n | no | yes | no | true | false |
"" | no | yes | no | true | false |
null | no | no | no | true | false |
undefined | no | no | no | true | false |
NaN | no | no | no | true | false |
Notice: null and undefined are falsy but do not == false. They only == each other. This is a special case in JavaScript's loose equality rules.
Type Coercion Quick Reference
// Explicit boolean conversion
Boolean(value) // recommended for clarity
!!value // common shorthand
// Explicit checks (safer than truthy/falsy)
value === null
value === undefined
value == null // true for both null and undefined
typeof value === "string"
Array.isArray(value)When to Use Truthy/Falsy Checks vs Explicit Comparisons
| Situation | Use truthy/falsy | Use explicit check |
|---|---|---|
| Check if a string has content | if (str) | - |
| Check if a value exists | if (val) | if (val != null) when 0/"" are valid |
| Check for null/undefined only | - | if (val != null) or if (val ?? false) |
| Validate a number | - | if (typeof n === "number" && !isNaN(n)) |
| Check array has items | if (arr.length) | if (arr.length > 0) |
Rune AI
Key Insights
- Only 8 falsy values exist:
false,0,-0,0n,"",null,undefined,NaN - Empty arrays and objects are truthy: check
.lengthfor arrays,Object.keys()for objects - Use
??instead of||for defaults: when0or""are valid values,??preserves them Boolean()and!!are equivalent: both convert values to their truthy/falsy boolean representation- Use explicit checks for numbers:
0is falsy, soif (count)fails when count is zero
Frequently Asked Questions
Why is an empty array truthy?
What is the difference between == false and being falsy?
Should I use Boolean() or !! to convert values?
Is document.all truthy or falsy?
How do truthy and falsy values affect switch statements?
Conclusion
Truthy and falsy values are one of JavaScript's core mechanics. There are exactly 8 falsy values: false, 0, -0, 0n, "", null, undefined, and NaN. Everything else is truthy, including empty arrays, empty objects, the string "0", and the string "false". Use truthy/falsy checks for simple existence testing (like checking if a string has content), but switch to explicit comparisons when 0 or empty strings are valid values. The ?? (nullish coalescing) operator replaces only null and undefined, making it safer than || for default values when falsy inputs are legitimate.
More in this topic
OffscreenCanvas API in JS for UI Performance
Master the OffscreenCanvas API to offload rendering from the main thread. Covers worker-based 2D and WebGL rendering, animation loops inside workers, bitmap transfer, double buffering, chart rendering pipelines, image processing, and performance measurement strategies.
Advanced Web Workers for High Performance JS
Master Web Workers for truly parallel JavaScript execution. Covers dedicated and shared workers, structured cloning, transferable objects, SharedArrayBuffer with Atomics, worker pools, task scheduling, Comlink RPC patterns, module workers, and performance profiling strategies.
JavaScript Macros and Abstract Code Generation
Master JavaScript code generation techniques for compile-time and runtime metaprogramming. Covers AST manipulation, Babel plugin authorship, tagged template literals as macros, code generation pipelines, source-to-source transformation, compile-time evaluation, and safe eval alternatives.