JavaScript • Syntax and Core Types

Truthy/Falsy Values — Explain truthy/falsy values and common pitfalls (conceptual)

Understand how JavaScript decides what counts as true or false beyond simple booleans.

JavaScript emblem with code brackets, braces, and a code file.
Inside this lesson 10 sections 5 questions 5 figures

SECTION 1

Historical Context & Motivation

Programming languages have always needed a way to make decisions. At the heart of every if statement, every loop, and every conditional check lies a simple question: is this condition true or false? Early languages like C allowed programmers to use numbers as stand-ins for boolean values—zero meant false and any nonzero number meant true. JavaScript inherited and expanded this idea, creating a system where every single value in the language can be treated as either true or false, even if it is not actually a boolean.

1972 • C Language Establishes 0 = False

The C programming language sets the convention that the integer 0 means false and any nonzero integer means true. This idea influenced nearly every language that came after.

1995 • JavaScript Is Created

Brendan Eich creates JavaScript in just 10 days. He builds in automatic type coercion, meaning values of any type can be used in boolean contexts—a design choice that makes JS both flexible and tricky.

1997 • ECMAScript 1 Formalizes the Rules

The first ECMAScript specification formally defines the ToBoolean abstract operation, listing exactly which values convert to false and which convert to true.

2015 • ES6 and Beyond

ECMAScript 2015 introduces Symbol and later BigInt, expanding the list of types. The falsy/truthy rules are extended to handle these new types consistently.

This history raises an essential question: if JavaScript allows any value to stand in for true or false, how does it decide which values count as which? And what happens when the results surprise us? Those are exactly the questions this lesson answers.

SECTION 2

Core Principles & Definitions

When JavaScript encounters a value in a boolean context—like the condition inside an if statement—it performs an invisible conversion called type coercion. Type coercion is JavaScript's way of automatically converting a value from one data type to another. In this case, it converts whatever value you provide into a boolean (true or false). A value that converts to true is called truthy, and a value that converts to false is called falsy.

1

Falsy Values

There are exactly eight falsy values in JavaScript: false, 0, -0, 0n, "", null, undefined, and NaN. Memorize these—everything else is truthy.
2

Truthy Values

Any value not on the falsy list is truthy. This includes all objects (even empty ones like [] and {}), all nonzero numbers, all non-empty strings, and the special value Infinity.
3

Boolean Context

A boolean context is any place where JavaScript expects a true/false answer: if conditions, while loops, ternary operators, and logical operators like && and ||.
4

The ToBoolean Operation

Internally, JavaScript follows the ToBoolean algorithm defined in the ECMAScript spec. You can trigger it yourself by calling Boolean(value) or using the double-NOT trick: !!value.
✦

KEY TAKEAWAY

Think of truthiness like a light switch. The default position is ON (truthy)—the switch is already flipped up for most values. Only a small, specific group of eight values can flip the switch OFF (falsy). If you memorize the short list of falsy values, you automatically know that everything else is truthy—just like knowing which eight switches are off tells you every other light in the building is on.

SECTION 3

Visual Explanation

The Truthy / Falsy UniverseFALSY VALUES (only 8)false← the literal boolean0← zero-0← negative zero0n← BigInt zero""← empty stringnull← intentional absenceundefined← not yet assignedNaN← not a numberBoolean(value) → falseTRUTHY VALUES (everything else)true42, -3, 3.14"hello", "0", " "[], [0], [1,2]{}, { a: 1 }Infinity, -Infinityfunction() {}new Date()Symbol()Boolean(value) → true
The diagram shows the complete split: the red box on the left contains all eight falsy values, while the green box on the right represents the infinite set of truthy values. Notice that "0" (the string containing zero) and [] (an empty array) are both truthy—common sources of confusion!

The visual above is the single most important reference in this lesson. Study the left side carefully and commit those eight falsy values to memory. Everything you encounter in the green column—and the countless values not even listed there—will behave as true inside an if statement. This asymmetry is by design: JavaScript assumes your data is "something" (truthy) unless it is specifically "nothing" (falsy).

SECTION 4

How Type Coercion Works

JavaScript does not just "guess" whether a value is truthy or falsy. Internally, the engine follows a precise algorithm called ToBoolean, defined in the ECMAScript specification. This algorithm checks the type of the value first, then applies a simple rule for that type.

Input TypeResultRule
BooleanNo conversion neededReturn the value as-is
Numberfalse if 0, -0, or NaNAll other numbers → true
BigIntfalse if 0nAll other BigInts → true
Stringfalse if "" (empty)Any string with at least one character → true
nullAlways falseNo exceptions
undefinedAlways falseNo exceptions
SymbolAlways trueEvery symbol is truthy
ObjectAlways trueAll objects, including empty arrays and objects

The ToBoolean algorithm by input type

Notice two critical takeaways from this table. First, the rule for objects is absolute: every object is truthy, no matter what it contains. An empty array [] is an object, so it is truthy. An empty object {} is truthy. Even new Boolean(false)—a Boolean wrapper object containing false—is truthy because it is still an object. Second, for strings the rule is purely about length: a string with even a single space " " is truthy because it is not empty.

💡

Boolean() vs. Double-NOT (!!)

You can test any value's truthiness in the browser console. Type Boolean([]) and you'll see true. The shorthand !![] does the same thing: the first ! flips the value to its boolean opposite, and the second ! flips it back, giving you the true boolean equivalent.

SECTION 5

Common Pitfalls & Surprises

Now that you know the rules, let's explore the places where developers—beginners and professionals alike—get tripped up. These pitfalls arise because our human intuition about "emptiness" doesn't always match JavaScript's formal definition.

Common Pitfalls: What You Expect vs. What HappensPITFALL 1: Empty Array is Truthyif ([]) { /* This RUNS! */ }[] is an object → always truthy, even though it has no elementsPITFALL 2: The String "0" is Truthyif ("0") { /* This RUNS! */ }"0" has length 1 → truthy. Only "" (empty string) is falsy.PITFALL 3: The String "false" is Truthyif ("false") { /* This RUNS! */ }"false" is a non-empty string → truthy. It is NOT the boolean false.PITFALL 4: NaN is Not Equal to ItselfNaN === NaN // false! Boolean(NaN) // falseNaN is falsy AND fails equality checks. Use Number.isNaN() instead.PITFALL 5: Whitespace Strings are TruthyBoolean(" ") // true — spaces count as characters
Each card above shows a common trap. The most dangerous is Pitfall 1 (empty array) because many beginners expect [] to be falsy like an "empty" thing. Remember: arrays are objects, and all objects are truthy.
💡

Pro Tip: Check Array Length Instead

If you want to check whether an array has items, don't use if (myArray) because that will always be true (the array exists). Instead, use if (myArray.length). The .length property returns a number—if the array is empty, that number is 0 (falsy); if it has items, it's a positive number (truthy).

SECTION 6

Worked Example

Let's walk through a realistic scenario. Imagine you are building a greeting function that should display a user's name if one is provided, or a default greeting otherwise.

Using Truthiness for Default Values

  1. 1

    Step 1 — Write the function

    We write a function that takes a username parameter and uses the logical OR operator (||) to set a default. The code is: const displayName = username || "Guest";
  2. 2

    Step 2 — Test with a normal string

    If username = "Alice", then JavaScript evaluates "Alice" || "Guest". Since "Alice" is a non-empty string (truthy), the || operator returns the left side immediately.
    displayName is "Alice" ✓
  3. 3

    Step 3 — Test with an empty string

    If username = "", then JavaScript evaluates "" || "Guest". The empty string is falsy, so the || operator skips it and returns the right side.
    displayName is "Guest" ✓
  4. 4

    Step 4 — Test with undefined (no argument passed)

    If the function is called with no argument, username is undefined, which is falsy. Again, || returns the right side.
    displayName is "Guest" ✓
  5. 5

    Step 5 — Spot the hidden pitfall

    What if username = 0? Maybe 0 is a valid user ID displayed as a name. Since 0 is falsy, 0 || "Guest" returns "Guest"—ignoring the valid value! This is why the nullish coalescing operator (??) was added in ES2020. It only falls back to the default for null or undefined, not for other falsy values like 0 or "".
    Use username ?? "Guest" when 0 or "" are valid inputs

SECTION 7

Loose Equality vs. Strict Equality

Truthy and falsy behavior is closely related to another JavaScript feature: loose equality (==) versus strict equality (===). While truthy/falsy deals with boolean conversion, loose equality adds another layer of type coercion that can produce unexpected results.

Expression== (Loose)=== (Strict)Why?
0 == falsetruefalseLoose equality converts false to 0
"" == falsetruefalseBoth convert to 0 during comparison
"0" == falsetruefalseCoercion: "0" → 0, false → 0
null == undefinedtruefalseSpecial rule: they equal each other loosely but nothing else
[] == falsetruefalse[] converts to "" then to 0; false converts to 0

Loose vs. strict equality with falsy values

✦

KEY TAKEAWAY

The last row of the table is especially confusing: [] is truthy (it passes an if check), yet [] == false returns true. This happens because truthiness and loose equality use different coercion algorithms. The safest approach is to always use === (strict equality), which never converts types. Think of == like a friend who "rounds up" your test score to be nice, while === is a teacher who only accepts the exact answer.

SECTION 8

Connection to Advanced Patterns

Understanding truthy and falsy values is not just about if statements—it unlocks several powerful JavaScript patterns you will encounter as you advance. Here is how the concept connects to more sophisticated tools.

ConceptHow It Uses TruthinessWhen You'll Learn It
Short-circuit evaluation&& returns the first falsy value it finds (or the last value). || returns the first truthy value.Intermediate JS
Nullish coalescing (??)Only treats null and undefined as "missing," unlike || which treats all falsy values as missing.ES2020+
Optional chaining (?.)Stops evaluation and returns undefined if a value is null or undefined—both falsy.ES2020+
Array filteringarr.filter(Boolean) removes all falsy values from an array by using Boolean as the callback function.Array methods
React conditional renderingPatterns like {items.length && <List />} rely on truthiness to decide whether to render a component.React / front-end

How truthy/falsy connects to advanced JavaScript

As you can see, mastering truthy and falsy values is foundational. Nearly every advanced pattern in JavaScript builds on the assumption that you understand which values JavaScript treats as "something" versus "nothing". In frameworks like React, a misunderstanding of truthiness can cause entire UI components to appear or disappear unexpectedly. Getting comfortable with these rules now will save you hours of debugging later.

SECTION 9

Practice Problems

Question 1: CONCEPTUAL

List all eight falsy values in JavaScript. Then explain in your own words why an empty array [] is NOT included in this list, even though it appears to be "empty."
Show answer
The eight falsy values are: false, 0, -0, 0n, "" (empty string), null, undefined, and NaN. An empty array [] is not falsy because it is an object. The ToBoolean algorithm treats all objects as truthy regardless of their contents. An array's "emptiness" refers to having no elements, but the array object itself still exists in memory, so JavaScript considers it truthy.

Question 2: BASIC CALCULATION

Predict the output of each expression: (a) Boolean("") (b) Boolean(" ") (c) Boolean(0) (d) Boolean("0") (e) Boolean(null)
Show answer
(a) false — the empty string is one of the eight falsy values. (b) true — a string containing a single space has a length of 1, so it is non-empty and therefore truthy. (c) false — the number 0 is falsy. (d) true — this is the string "0" (one character long), not the number 0; any non-empty string is truthy. (e) false — null is always falsy.

Question 3: INTERMEDIATE

Consider this code: let count = 0; const result = count || 10; What is result? Is this behavior desirable if count is supposed to represent a valid count of zero? How would you fix it using a modern JavaScript operator?
Show answer
The value of result is 10. Because 0 is falsy, the || operator skips it and returns the right-hand operand. This is NOT desirable if 0 is a meaningful count. To fix it, use the nullish coalescing operator: const result = count ?? 10;. The ?? operator only falls back to 10 if count is null or undefined, allowing 0 to be preserved as a valid value.

Question 4: APPLIED

You are building a search feature. Users type into a search box, and you want to display results only when the user has typed something. You write: if (searchTerm) { showResults(); }. A user reports that typing "0" into the search box produces no results, even though there are items matching "0" in the database. Explain the bug and propose a fix.
Show answer
Wait—this one is actually a trick question to test careful thinking! The string "0" is truthy (it has one character), so if (searchTerm) would actually pass when searchTerm is "0". The bug must be elsewhere—perhaps the code is converting the string to a number before the check, e.g., if (Number(searchTerm)), which would convert "0" to the number 0 (falsy). The fix is to check the string directly: if (searchTerm.length > 0) or simply if (searchTerm !== ""). This ensures you are checking string emptiness rather than relying on type coercion.

Question 5: CRITICAL THINKING

Explain why [] == false returns true, yet if ([]) also enters the truthy branch. How can the same value be both "equal to false" and "truthy" at the same time? What lesson does this teach about using == versus ===?
Show answer
These two operations use different coercion algorithms. The if ([]) statement uses the ToBoolean algorithm, which says all objects are truthy—so the branch executes. However, [] == false uses the Abstract Equality algorithm, which converts both sides step by step: [] is converted to the primitive "" (via toString), then "" becomes 0; false also becomes 0. Since 0 equals 0, the result is true. This seeming contradiction is exactly why professionals recommend always using === (strict equality), which skips all coercion. With strict equality, [] === false returns false because an object and a boolean are different types.

SUMMARY

Lesson Summary

Summary

JavaScript automatically converts any value to a boolean when it appears in a boolean context (like an if condition). Values that convert to true are called truthy, and values that convert to false are called falsy. There are exactly eight falsy values: false, 0, -0, 0n, "", null, undefined, and NaN. Everything else—including empty arrays and objects—is truthy.

The biggest pitfalls come from values that feel empty but are truthy ([], "0", "false") and from mixing up truthiness with loose equality (==). Use strict equality (===) to avoid coercion surprises, and use the nullish coalescing operator (??) instead of || when 0 or "" are valid values in your program.

Varsity Tutors • JavaScript • Truthy/Falsy Values