A value is falsy if it converts to false, and exactly nine values do; everything else, including every object, is truthy. ! negates, and !!value or Boolean(value) converts explicitly. && and || short-circuit and return one of their operands, not a Boolean: a && b gives a if it is falsy, otherwise b; a || b gives a if it is truthy, otherwise b. a ?? b falls back only when a is null or undefined.
| Type | Falsy values | Truthy surprises |
|---|---|---|
| Boolean | false | new Boolean(false) |
| Number, BigInt | 0, -0, NaN, 0n | -1, Infinity |
| String | "" | "0", "false", " " |
| Undefined, Null | undefined, null | none |
| Object | document.all (browsers only) | [], {} |
const samples = [0, -0, 0n, "", NaN, "0", "false", [], {}, new Boolean(false)];
console.log(samples.map(Boolean).join(" "));
console.log("a" && 0 && "never", null || "" || "last", 0 ?? 42);
const config = { retries: 0, title: "" };
config.retries ||= 3; // replaces 0: usually a bug
config.title ??= "Untitled"; // keeps "": only null/undefined count
console.log(config);false false false false false true true true true true
0 last 0
{ retries: 3, title: '' }Test arrays with arr.length > 0, never if (arr). document.all is a legacy object that the HTML standard makes falsy on purpose so that old Internet Explorer checks stay dormant. Mixing ?? with || or && without parentheses is a SyntaxError. And == ignores truthiness: [] == false is true although [] is truthy.