# Equality and Truthy Values

JavaScript has a loose == that converts types before comparing and a strict === that doesn't, and it treats every value as truthy or falsy in a condition, so you learn which to use and where 0 and empty text trip people up.

Apprentice · JavaScript · Updated November 1, 2026

## After this lesson you can

- Compare values with === and !==, and predict what == does when the types differ
- Tell truthy values from falsy ones and predict which branch of an if runs

## Key takeaways

- === (strictly equal) is true only when the values and their types match. == (loosely equal) converts the types first, which gives surprises such as 0 == "" being true.
- Use === and !== for your comparisons. When the types differ, convert one value yourself first, for example with Number().
- Six values are falsy (they act like false in a condition): false, 0, "", null, undefined and NaN. Every other value is truthy, even "0", "false" and an empty array.
- if (value) is a quick way to ask "is there anything here?", but it treats 0 and "" as nothing, even when they're real answers.

A runner at the Riverside 5K types her bib number into the check-in form: `7`. The sheet says runner 7 is Maria Lopez. Is she checked in? That depends on how your code asks "are these equal?", because everything typed into a form arrives as text, and `"7"` the text isn't `7` the number. The same goes for "did they fill in their name?" and "did they pick a shirt size?". You'll write checks like these in every form, search box and game you build, and this lesson shows the two places where JavaScript surprises people: its two kinds of equal, and the values it treats as "nothing".

## Two ways to ask "are these equal?"

Picture two price tags: one says *7* in handwriting, the other is a 7 printed by a register. A relaxed shop assistant says "same price". A strict one says "same number, but one is handwritten, so not the same thing". JavaScript has both:

- `===` is read "triple equals" or "strictly equal". It's `true` only when the values match **and** their types match. You met it in *Booleans and Comparisons*.
- `==` is read "double equals" or "loosely equal". When the types differ, it first converts one value to the other's type, then compares.

```javascript
const bibFromForm = "7";
const bibOnSheet = 7;

console.log(bibFromForm == bibOnSheet);
console.log(bibFromForm === bibOnSheet);
console.log(Number(bibFromForm) === bibOnSheet);
```

```text
true
false
true
```

The last line is the honest way to do it: you convert the text to a number yourself, with `Number()` from *Types and Converting Between Them*, then compare strictly. Anyone reading the code can see exactly what happens.

## Why == surprises people

The conversion `==` does is called **type coercion**: JavaScript coerces (forces) a value into another type without being asked. Its rules are long, and some results look wrong even to people who know them:

```javascript
console.log(0 == "");
console.log("0" == false);
console.log(" " == 0);
console.log(null == undefined);
console.log(null == false);
```

```text
true
true
true
true
false
```

An empty name box equal to a score of 0? A space equal to 0? That's coercion at work, and it's how bugs slip through a check that looks right. The not-equal pair works the same way: `!==` (read "not strictly equal") compares strictly, and `!=` (read "not equal") converts first. So the rule most teams follow is short: **use `===` and `!==`**. You'll still see `==` in older code, and now you know to read it carefully.

![Two scales side by side: the loose == scale converts the text "7" into the number 7 before weighing, so it balances; the strict === scale weighs them as they are, text against a number, so it doesn't](https://fsdtrainingmedia.blob.core.windows.net/public/images/2026/10/247913c37b9849b793b56146b462413e.webp)

## Truthy and falsy

An `if` asks a yes-or-no question, and it expects `true` or `false`. Give it any other value and JavaScript decides whether that value *counts as* true. Think of a volunteer at the check-in table glancing at a form: "is anything written here?"

A value that counts as false is **falsy**. There are six you need to know:

| Falsy value | What it is |
|---|---|
| `false` | the boolean false |
| `0` | the number zero |
| `""` | an empty string, with nothing between the quotes |
| `null` | "deliberately empty" (next lesson) |
| `undefined` | "nothing was ever put here" (next lesson) |
| `NaN` | "not a number", the result of a calculation that failed |

Every other value is **truthy**: it counts as true. That includes some that look false. `Boolean(value)` shows you how a value counts:

```javascript
console.log(Boolean(""));
console.log(Boolean("0"));
console.log(Boolean(" "));
console.log(Boolean("false"));
console.log(Boolean([]));
console.log(Boolean(NaN));
```

```text
false
true
true
true
true
false
```

`"0"` and `"false"` are strings with characters in them, so they're truthy; so is a string holding one space, and so is an empty array. (Two rare numbers are falsy too, `-0` and `0n`, but you won't meet them often.)

## if (value): a quick "is anything here?"

Because of truthy and falsy, you can put a value straight into an `if`. It reads like a question: *if there's a name, greet them; otherwise ask for one*.

```javascript
const nameFromForm = "";

if (nameFromForm) {
  console.log(`Welcome, ${nameFromForm}!`);
} else {
  console.log("Please enter your name.");
}
```

```text
Please enter your name.
```

Try `"Maria"` instead of `""`, and the welcome prints. The `!` you met in *Combining Conditions with And, Or and Not* (read "not") flips it: `if (!nameFromForm)` means "if there's no name".

**Try it.** Make a file named `truthy.js` that loops over `[0, "", "0", "Maria", null, [], NaN, 42]` with `for...of` and prints each value and `Boolean(value)` on one line. Guess each answer before you run `node truthy.js`.

## When falsy bites: 0 and "" are real answers

The shortcut has a trap. Some runners bring guests to cheer, and the form asks how many. Priya typed 0. Look what a quick truthy check does with her honest answer:

```javascript
const guests = 0;

if (guests) {
  console.log(`Guest passes: ${guests}`);
} else {
  console.log("Guests: not answered yet");
}

if (guests !== undefined) {
  console.log(`Guest passes: ${guests}`);
}
```

```text
Guests: not answered yet
Guest passes: 0
```

0 is falsy, so the first check thinks Priya never answered. When 0 or `""` is a real answer, ask exactly what you mean, as the second check does: *was a value given at all?* The next lesson, *Missing Values: null, undefined, ?. and ??*, gives you a tidier tool for exactly this.

## Check yourself

2 questions to try on the lesson page.

## So what

Most "it works on my machine but not with real data" bugs in a form come from a loose comparison or a 0 treated as nothing. Compare with `===`, and use `if (value)` only when 0 and empty text really mean "nothing here".

## Key terms

- [Strict Equality (===)](https://www.ask-codey.com/glossary/strict-equality)
- Loose Equality (==)
- [Type Coercion](https://www.ask-codey.com/glossary/type-coercion)
- [Truthy](https://www.ask-codey.com/glossary/truthy)
- [Falsy](https://www.ask-codey.com/glossary/falsy)
- [NaN](https://www.ask-codey.com/glossary/nan)

## Cheat sheets

- [Equality and Truthy Values](https://www.ask-codey.com/cheat-sheets/javascript-tricky-values-equality-and-truthiness-cheat-sheet)

## Related

- [Booleans and Comparisons](https://www.ask-codey.com/lessons/javascript-booleans-and-comparisons)
- [Types and Converting Between Them](https://www.ask-codey.com/lessons/javascript-types-and-converting)

Source: https://www.ask-codey.com/lessons/javascript-tricky-values-equality-and-truthiness
