Programs, values, and types · Lesson 5 of 77 · concept

True, false, and comparing values

About 45 minutes.

By the end of this lesson you can

  • Name the two boolean values and produce them with comparison operators.
  • Use === and !== and say why they never convert their operands.
  • Predict how two pieces of text compare, including capital letters and digits.
  • Spot the two classic comparison traps: chained comparisons and a single equals sign.

A type with exactly two values in it

Explanation

Numbers are endless and text is endless, but the BOOLEAN type has exactly two values in the whole language: true and false. They are written as bare words with no quotes. The word "true" in quotes is a piece of text, not a boolean, and confusing the two causes real bugs.

Booleans are what decisions are made of. In the next module, every if, every loop condition and every filter comes down to a value that is one of these two. Getting comfortable producing them accurately now is what makes that module easy.

Comparison operators are just expressions that produce true or false

Explanation

There is nothing special about a comparison. 3 < 5 is an expression that produces a value, in the same way 3 + 5 is; the value it produces just happens to be true rather than 8. You can name it, print it, and pass it around exactly like any other value.

The relational operators are < less than, > greater than, <= less than or equal to, and >= greater than or equal to. For equality there are === is exactly equal to and !== is not exactly equal to. There is also a two-character == which behaves differently and which the last lesson of this module is entirely about; until then, use three.

Reading them out loud helps more than it should. isReady === true reads as "is ready is exactly equal to true", which immediately sounds like something you would never say — and indeed isReady on its own already is the boolean, so comparing it to true adds nothing.

What === actually promises

Explanation

=== asks a narrow, honest question: are these the same type, and are they the same value? If the two sides are different types the answer is false immediately, with no attempt to convert anything. So 3 === 3 is true, and "3" === 3 is false, because one is a number and the other is text.

That refusal to convert is the entire point, and it is why every style guide reaches for === by default. A comparison that quietly converts its operands can be true for reasons you did not intend, and finding out why is a bad afternoon.

One exception exists, and it is the one you met in the numbers lesson: NaN === NaN is false. Every comparison involving NaN is false, including that one, which is why Number.isNaN exists.

Comparing text is dictionary order, but not the dictionary you know

Explanation

When both sides of <, >, <= or >= are text, JavaScript compares them character by character until it finds a pair that differs, and decides based on that pair. "apple" < "banana" is true because a comes before b.

The order it uses is the numeric order of the underlying character codes, not the order a dictionary or a phone book would use. In that scheme every capital letter comes before every lower-case one, so "Zebra" < "apple" is true — which is emphatically not what a human sorting a list would do.

Digits inside text follow the same rule, with a result that catches everybody: "10" < "9" is true, because the comparison stops at the first character, and 1 comes before 9. If you want the numeric answer, compare numbers rather than text. Real alphabetical sorting of human-facing lists needs localeCompare, which the text module covers.

MDN — Less than (<)

Check there: That when both operands are strings they are compared as sequences of UTF-16 code units, not by locale-aware alphabetical order.

The two traps that look like they should work

A common mistake

Chaining comparisons. In mathematics 1 < 2 < 3 means what you think it means. In JavaScript it is worked out left to right: 1 < 2 gives true, and then true < 3 is compared, which quietly turns true into 1 and asks 1 < 3. The answer happens to be true, which is worse than being wrong, because the same shape gives 3 > 2 > 1 as false. Never chain. Write two comparisons and join them, which the next module shows you how to do.

One equals sign instead of three. A single = does not compare anything: it assigns. Writing it where you meant a comparison either changes a value you did not mean to change or fails outright, depending on what is on the left. If you remember one piece of punctuation from this lesson, remember that = means becomes and === means is equal to.

Flipping an answer with !

Explanation

An exclamation mark in front of a boolean flips it: !true is false and !false is true. It is pronounced not, so !isOutOfStock reads as not out of stock.

Two of them in a row, !!, flip it twice and therefore change nothing about a boolean. You will see !!value in real code, where it is being used on a value that is not a boolean to force it into one — a trick that only makes sense once you have met truthiness in the next module.

A style note that will save you: name booleans so they read as a claim that is either true or false. isLow, hasEnough, wasFound. A boolean named status or check tells the next reader nothing, and the next reader is usually you.

Recap

Recap

The boolean type holds exactly true and false. Comparisons are ordinary expressions that produce them. === compares type and value with no conversion, and is the default. Text compares by character code, so capitals sort before lower case and "10" is less than "9". Never chain comparisons, never write = where you meant ===.

Worked examples

Every output below was produced by actually running the code in the same sandbox your exercises run in — it is not a prediction.

Six comparisons, six values

Each line is an expression producing true or false. The fourth is the one to slow down on: same-looking, different types.

1console.log(3 < 5);2console.log(3 > 5);3console.log(3 === 3);4console.log("3" === 3);5console.log(3 !== 4);6console.log(!true);
  • line 4

    Text 3 against number 3. Different types, so === answers false without looking any further. This is the behaviour you want.

  • line 5

    !== is the opposite of ===: true when they are not exactly equal.

  • line 6

    ! flips a boolean. Nothing is being compared here at all.

What it prints

truefalsetruefalsetruefalse

How text really sorts

Three of these four results are surprising the first time. All four follow one rule: compare character codes, left to right, stop at the first difference.

1console.log("apple" < "banana");2console.log("Zebra" < "apple");3console.log("apple" === "Apple");4console.log("10" < "9");
  • line 1

    First differing pair is a against b, and a has the lower code. True.

  • line 2

    Capital Z has a lower code than lower-case a, so every capitalised word sorts before every lower-case one. Not what a reader expects from a sorted list.

  • line 3

    === on text is exact, and case is part of exact.

  • line 4

    The comparison stops at the first character: 1 against 9. It never reaches the 0, so the text 10 is less than the text 9. Compare numbers if you want the numeric answer.

What it prints

truetruefalsetrue

Why chained comparisons lie

The same shape gives a right-looking answer once and a wrong one immediately after. Read the second result and the reason together.

1console.log(1 < 2 < 3);2console.log(3 > 2 > 1);
  • line 1

    Left to right: 1 < 2 is true, then true < 3 turns true into 1 and asks 1 < 3. True — by accident.

  • line 2

    Same machinery: 3 > 2 is true, then true > 1 becomes 1 > 1, which is false. Mathematically the statement is obviously true, so the language is not answering the question you asked.

What it prints

truefalse

Check yourself

Not scored, not stored. Getting one wrong is the useful part.

Two comparisons on the same value. What does each print?

const stock = 0;console.log(stock === 0);console.log(stock !== 0);

What does 3 > 2 > 1 produce, and why?

Which of these is true?

Write it yourself

Exercise · core · 5 tests

Three flags for a stock level

A shop holds 3 of an item and reorders when it drops below 5. Declare three booleans, each PRODUCED BY A COMPARISON rather than typed in by hand: isLow (stock is below the reorder level), isOutOfStock (stock is exactly zero) and hasEnough (stock is at or above the reorder level).

What your code must do

With stock 3 and reorderLevel 5, isLow is true, isOutOfStock is false and hasEnough is false. Each value must be a boolean. The tests read the three values; they cannot tell whether you compared or simply typed true and false, so the honesty of this one is yours — write the comparisons, then change stock to 7 and re-run to watch all three answers move.

Define isLow, isOutOfStock and hasEnough at the top level of your code — the tests call them by name.

Runs on your device in a sandbox with no network and no access to this page.

Worth remembering

  • What does === do that == does not?

    It refuses to convert. If the two operands are different types the answer is false straight away, so a comparison can never be true for a reason you did not intend.

  • Why is "10" < "9" true?

    Text is compared character by character using character codes, and the comparison stops at the first difference: 1 comes before 9. Compare numbers if you want the numeric answer.

  • Why must you never write a < b < c?

    It is worked out left to right, so the first comparison produces a boolean that the second one converts to 1 or 0. The result is meaningless — 3 > 2 > 1 is false.

Check this lesson against the source

We wrote the explanation; we did not invent the facts. This is the page that backs them.

MDN — Expressions and operators

Check there: The Comparison operators section: a comparison operator compares its operands and returns a logical value; and the note that === does not convert types.

MDN — Strict equality (===)

Check there: That operands of different types are never equal, and that NaN is not equal to anything including itself.

MDN — Boolean

Check there: That the boolean type has the two values true and false.

Prefer to read the source in a structured breakdown? Turn this doc into a breakdown

0 of 1 exercise in this lesson solved on this device

Consent version 2026-07-31.1

Cookie preferences