ESC

Type to search the knowledge base.

Truthy and Falsy Values

Memorize JS falsy list, avoid || default traps with 0 and '', and prefer Boolean() / ?? for intent-clear checks.

beginner3 min read
  • javascript
  • truthy-and

In boolean contexts (if, while, &&, ||, ternary), values coerce to true or false. Falsy values are a short fixed list; everything else is truthy — including [], {}, and "0".

The falsy list (memorize)

false
0
-0
0n          // BigInt zero
''          // empty string
null
undefined
NaN

That’s it. No, empty arrays are not falsy.

if ([]) console.log('runs');     // truthy
if ({}) console.log('runs');     // truthy
if ('0') console.log('runs');    // truthy string
if (new Boolean(false)) console.log('runs'); // object wrapper is truthy!

Coercion helpers

Boolean(x);
!!x; // common idiom

Prefer explicit checks when zero/empty string are valid:

// BAD for counts
const count = input || 10; // 0 becomes 10

// GOOD
const count = input ?? 10;
// or
const count = input === undefined || input === null ? 10 : input;

&& and || return values, not booleans

0 || 'default'; // 'default'
2 || 'default'; // 2
1 && 2 && 3;    // 3
1 && 0 && 3;    // 0

Short-circuit:

user && user.name;
// today: user?.name

Truthy checks that lie

const items = [];
if (items) {
  // always true even when empty
}
if (items.length) {
  // empty check
}

const map = new Map();
if (map) { /* always */ }
if (map.size) { /* has entries */ }

Document all-in-one table

Value Boolean
false false
0, -0, 0n false
'' false
null, undefined false
NaN false
'false', '0' true
[], {} true
function(){} true

Form and API data

// checkbox unchecked may be missing; input values are strings
if (formData.get('qty')) { /* '0' is truthy! */ }
if (Number(formData.get('qty'))) { /* 0 is falsy — maybe OK for qty */ }

Parse then validate with explicit rules, not raw truthiness.

Interview answer (out loud)

“Falsy values are false, 0, -0, 0n, empty string, null, undefined, and NaN. Everything else is truthy, including empty arrays and objects. I use ?? for nullish defaults so 0 and ‘’ survive, and I check .length/.size for empty collections.”

Double bang and Boolean in maps

const flags = values.map(Boolean);
const flags2 = values.map((v) => !!v);

Useful when normalizing API fields that arrive as 0|1 or messy types — still better to parse intentionally when 0 is data.

React rendering

{count && <Badge n={count} />}
// count=0 → renders 0 in React DOM — classic footgun

{count > 0 && <Badge n={count} />}
{!!count && <Badge n={count} />}
{count ? <Badge n={count} /> : null}

Truthy checks in JSX are not free of display side effects.

Document.all (archaeology)

Legacy document.all is falsy in a special weird way in browsers — don’t use it. Mention only if an interviewer goes deep on “are there other falsy objects?” Answer: not in modern portable JS; stick to the standard list.

Further reading

Related guides