Knowledge Base/concepts/Truthy and Falsy Values in JavaScript

Truthy and Falsy Values in JavaScript

Truthy and falsy values in JavaScript are not about what a value looks like. They are about what happens when JavaScript coerces that value to a boolean. That is why [] is truthy, "false" is truthy, and 0 is falsy. The rules are small, but they sit under almost every if, while, ? :, &&, and || you write.

The mistake is using truthiness when you really meant a more specific check.

The everyday falsy list

These values become false in a boolean context:

ValueWhy it matters
falseAlready a boolean false
0 and -0Numeric zero
0nBigInt zero
""Empty string
nullIntentional absence
undefinedMissing or unassigned value
NaNFailed numeric result

In browsers, document.all is a legacy special case that is also falsy. You will almost never use it, but it exists, because the web has a long memory and not all of it is pleasant.

Everything else is truthy.

Boolean(false); // false
Boolean(0); // false
Boolean(""); // false
Boolean(null); // false
Boolean(undefined); // false
Boolean(NaN); // false

Boolean("0"); // true
Boolean("false"); // true
Boolean([]); // true
Boolean({}); // true

The empty array trap

Developers often expect empty arrays and empty objects to be falsy because they feel empty. JavaScript does not care how they feel.

const users = [];

if (users) {
  console.log("This runs");
}

An array is an object, and objects are truthy. Check the thing you actually care about:

if (users.length > 0) {
  console.log("There are users");
}

For plain objects, check keys:

const settings = {};

if (Object.keys(settings).length > 0) {
  console.log("Settings exist");
}

Truthy checks are broad checks

This code is common:

if (username) {
  renderProfile(username);
}

It means "render if username is not falsy." That excludes "", null, and undefined, which is often fine.

But a truthy check may reject valid data:

function showScore(score) {
  if (score) {
    return `Score: ${score}`;
  }

  return "No score yet";
}

showScore(0); // "No score yet"

If 0 is a real score, the check is wrong. Use a narrower condition:

function showScore(score) {
  if (score !== null && score !== undefined) {
    return `Score: ${score}`;
  }

  return "No score yet";
}

Or use nullish coalescing when you want to treat only null and undefined as missing.

|| versus ??

The || operator returns the right-hand value when the left-hand value is falsy:

const pageSize = requestedPageSize || 20;

That works if every falsy value should fall back. It fails if 0 or "" are valid:

const maxItems = 0;
const limit = maxItems || 10;

console.log(limit); // 10

?? falls back only for null or undefined:

const maxItems = 0;
const limit = maxItems ?? 10;

console.log(limit); // 0

Use || for "any falsy value should use the default." Use ?? for "only missing values should use the default."

&& returns a value, not a boolean

&& is often used as a guard:

user && renderUser(user);

It does not return true or false by default. It returns one of the original values.

"Ada" && "active"; // "active"
"" && "active"; // ""

That can be useful, but be deliberate. If you need a real boolean, convert it:

const hasUser = Boolean(user);
const alsoHasUser = !!user;

Boolean(value) is clearer for teaching. !!value is common in codebases that prefer terseness.

Ternaries depend on the same rules

The JavaScript ternary operator uses the same truthy and falsy coercion:

const label = count ? `${count} items` : "No items";

Again, this treats 0 as "No items." That is probably right for a cart count. It might be wrong for a score, volume setting, or explicit numeric filter.

Key Takeaways

  • Falsy values include false, numeric zero, BigInt zero, empty string, null, undefined, and NaN.
  • Empty arrays and empty objects are truthy because all normal objects are truthy.
  • Truthy checks are broad. Use explicit comparisons when 0, "", or false are valid data.
  • || falls back on any falsy value. ?? falls back only on null or undefined.
  • Boolean coercion is useful, but it should match the exact meaning your code needs.
Share this article:
javascriptfundamentalstypesconditionals