Booleans
A boolean has only two values: true and false. They drive every conditional in your program — if, while, the ternary ? :, and the short-circuit operators &&, ||, ??. JavaScript adds a wrinkle most languages don't have: truthiness. Almost any value can stand in for a boolean in a conditional, and the rules for which values count as "true" or "false" are the source of more bugs than the boolean type itself.
The two values, and the type
const yes = true;
const no = false;
typeof yes; // "boolean"
typeof no; // "boolean"
// Never do this — wrapper objects behave weirdly:
const bad = new Boolean(false);
typeof bad; // "object"
if (bad) console.log("oh no"); // runs! because objects are truthy
// Use the function form (no `new`) to coerce
Boolean("hi"); // true
Boolean(0); // falseThe seven falsy values
Every value in JavaScript is either truthy or falsy. The complete list of falsy values is short and worth memorising — everything else is truthy.
false0and-00n(BigInt zero)""(empty string)nullundefinedNaN
Boolean(false); // false
Boolean(0); // false
Boolean(-0); // false
Boolean(0n); // false
Boolean(""); // false
Boolean(null); // false
Boolean(undefined); // false
Boolean(NaN); // false
// Everything else, including "surprising" things, is truthy
Boolean("false"); // true — non-empty string
Boolean("0"); // true — non-empty string
Boolean([]); // true — empty array is truthy
Boolean({}); // true — empty object is truthy
Boolean(() => {}); // true — functions are truthyThree ways to convert to boolean
Boolean(x); // explicit function call — clearest
!!x; // double-negation — short and idiomatic
x ? true : false; // ternary — verbose, not recommended
// All three give the same result
Boolean("hello"); // true
!!"hello"; // true
!!0; // false
!!{}; // trueComparison operators return booleans
5 > 3; // true
5 === "5"; // false — strict equality, different types
5 == "5"; // true — loose equality coerces, avoid
null == undefined; // true — by spec; the one quirk worth remembering
"abc".includes("b"); // true
[1,2,3].length === 3; // trueStick to === and !== by default. The loose == / != performs type coercion in surprising ways; the one place == is genuinely useful is x == null which is shorthand for "is x either null or undefined?".
Logical operators short-circuit
This is the part most often misunderstood: in JavaScript, && and || don't return booleans. They return one of their operands.
// && returns the first falsy operand, or the last operand if all are truthy true && "second"; // "second" "a" && "b" && "c"; // "c" 0 && "never"; // 0 null && "never"; // null // || returns the first truthy operand, or the last operand if all are falsy false || "fallback"; // "fallback" "" || 0 || "default"; // "default" null || undefined || 0; // 0 — all falsy, returns last // ! always returns a real boolean !true; // false !"anything truthy"; // false !0; // true
"second" "c" 0 null
Default-value patterns: || vs ??
Before ES2020 the standard "if missing, use this" pattern used ||. That breaks when the legitimate value is falsy — like 0 or "". The nullish coalescing operator ?? only falls back for null and undefined.
function setVolume(level) {
// BAD: a user setting volume to 0 gets the default 50 instead!
const v = level || 50;
return v;
}
function setVolumeBetter(level) {
// GOOD: only falls back if level is null or undefined
const v = level ?? 50;
return v;
}
setVolume(0); // 50 — wrong
setVolumeBetter(0); // 0 — correctBooleans inside conditionals
const items = [];
// Idiomatic, leans on truthiness
if (items.length) {
console.log("we have items");
} else {
console.log("empty");
}
// More explicit, often clearer in code reviews
if (items.length > 0) {
console.log("we have items");
}
// Short message picker
const status = isOnline ? "online" : "offline";
// Guard pattern — exit early
function greet(name) {
if (!name) return "hello, stranger";
return `hello, ${name}`;
}Boolean methods (mostly useless, briefly)
(true).toString(); // "true" (false).toString(); // "false" (true).valueOf(); // true String(false); // "false" JSON.stringify(true); // "true"
There isn't much surface area to learn: booleans serialise predictably and otherwise do their job by being passed around.
The mental model is small: two values, seven falsy values, short-circuit returns operands. Get those three things right and most of JavaScript's logic surprises disappear.