completefrontend
Open lab My progress
THE JAVASCRIPT FIELD GUIDE

Comparisons

Compare JavaScript values safely with strict equality, string ordering, careful null checks, and the right way to detect NaN.

By the end, you can
  • 01
    Pick the safe equality checkUse === to check if values are equal, and know when == changes a value first.
  • 02
    Predict which comes firstCompare strings, numbers, and a string with a number, and say the answer before you run it.
  • 03
    Handle the special valuesCheck null, undefined, and NaN with the right tool for each.

A comparison asks a yes-or-no question

A comparison checks two values and answers true or false. These two answers are called booleans. Your code uses a comparison whenever it must make a choice. For example:

  • Is the password long enough?
  • Did the score reach 100?
  • Is a value missing?
  • Should this item come before that one?

You met these values in earlier lessons: Data types, Numbers & math, Strings, and Booleans, null & undefined. This lesson is about the operators that compare them. An operator is a symbol that does a job, like + or ===.

The short version

Use === to check if two values are equal. It asks: "Same type, and same value?" Use == only when you want it to change values before it compares. The common case is value == null, which is true for both null and undefined.

Real-life analogyStrict equality is a careful door guard

Picture a guard at the door of a club. A careful guard checks the name on your ID card. The guard also checks what kind of card it is. A relaxed guard lets you in if the name is close enough, even on the wrong kind of card. === is the careful guard. == is the relaxed one.

In real life: The name on the ID card
In JavaScript: The value: 5, "5", false, null
In real life: The kind of ID card
In JavaScript: The type: number, string, boolean, and so on
In real life: A careful guard checks both
In JavaScript: === checks the type and the value
In real life: A relaxed guard accepts a close match
In JavaScript: == may change a value first, so "0" == 0 is true

In this lesson you will:

  • compare values in a live playground,
  • step through how text is put in order,
  • sort out null and undefined,
  • learn why NaN is the one value that equality can't find.

Strict === and loose ==

INTERACTIVE

JavaScript has two operators that check if two values are equal. The one you want most of the time is strict equality, written === (three equals signs). It gives true only when both sides have the same type and the same value.

Strict equality checks the type and the valuePop out in the code editor (opens in a new tab)JavaScript
const score = 5; console.log(score === 5);console.log("5" === score);console.log(false === 0);

Line 1 stores the number 5 in score. Line 3 prints true: both sides are the number 5. Line 4 prints false: the left side is the text "5", and the right side is a number. Line 5 also prints false: false is a boolean, and 0 is a number.

Loose equality is written == (two equals signs). It may change one side into another type before it compares. This change is called conversion. You saw it in the Type conversion lesson. Here, remember one thing: == can make two different-looking values count as equal.

Left: "5" === 5. One side is a string and one is a number, so the answer is false. Right: "5" == 5. JavaScript changes "5" into the number 5 first, so the answer is true."5" === 5"5"5stringnumberfalsetypes differ"5" == 5"5"5stringnumbertrue"5" becomes 5 first
The same two values, compared two ways. === sees a string and a number, so it says false. == first changes the string "5" into the number 5, so it says true.
Turn form text into a number before you comparePop out in the code editor (opens in a new tab)JavaScript
const ageText = "18";const age = Number(ageText); console.log(age === 18);console.log(Number.isNaN(age));

When a person types into a form on a web page, the browser gives you text, even if they typed a number. Line 1 holds that text, "18". Line 2 turns the text into a number once, with Number(). Line 4 prints true, because age is now the number 18.

Line 5 prints false. Number.isNaN() asks "is this NaN?" NaN is the value you get when turning something into a number fails. Here the change worked, so age is not NaN. NaN has its own section near the end.

Compare two values three ways
The code for your two valuesPop out in the code editor (opens in a new tab)JavaScript
const left = "0";const right = 0; console.log(left == right);console.log(left === right);console.log(Object.is(left, right));
Real answersChange the menus
==true
===false
Object.isfalse
Try it yourself

== turns the string into a number first. So text like "0" can equal the number 0.

Pick two values. The three answers come from JavaScript itself: ==, ===, and Object.is().

Try these pairs in the playground:

  • "0" and 0
  • "" and false
  • null and undefined

The answers come from JavaScript itself. The third answer uses Object.is(), another way to check if two values are the same. You met it in Numbers & math. The later "Equality & sameness" lesson covers it in full.

The table below shows what == gives for seven common values. Find the left value in the first column. Then find the right value along the top. The cell where they meet is the answer to left == right.

What == gives for seven common values
left == right0"0"""falsenullundefinedNaN
0truetruetruetruefalsefalsefalse
"0"truetruefalsetruefalsefalsefalse
""truefalsetruetruefalsefalsefalse
falsetruetruetruetruefalsefalsefalse
nullfalsefalsefalsefalsetruetruefalse
undefinedfalsefalsefalsefalsetruetruefalse
NaNfalsefalsefalsefalsefalsefalsefalse
A simple rule

If two values should be the same type, use ===. If one of them came from a text box, turn it into a number yourself first: Number(input) === 5. Then anyone reading the code can see what happens. They don't need to remember all the rules of ==.

Objects must be the same object

REAL OUTPUTS

Numbers, strings, booleans, null, and undefined are primitive values. They are simple, single values. For them, 3 === 3 just checks that the values match.

Objects and arrays work differently. For them, === asks: "Do both names point to the very same object?"

Two carts with the same totalPop out in the code editor (opens in a new tab)JavaScript
const firstCart = { total: 3 };const sameCart = firstCart;const otherCart = { total: 3 }; console.log(firstCart === sameCart);console.log(firstCart === otherCart);

Line 1 makes a cart with a total of 3 and calls it firstCart. Line 2 does not make a new cart. It gives the same cart a second name, sameCart. So line 5 prints true.

Line 3 makes a second, separate cart. It also starts with a total of 3. But it is a different cart, so line 6 prints false.

Two name tags, firstCart and sameCart, point to the same cart. A third tag, otherCart, points to a second cart. Both carts hold total 3.firstCartsameCartotherCarttotal: 3cart 1total: 3cart 2
firstCart and sameCart are two names for one cart, so firstCart === sameCart is true. otherCart is a second cart. It holds the same total, but it is not the same cart, so firstCart === otherCart is false.

The table puts simple values and objects side by side. Each row is one comparison, its answer, and the reason.

Comparing simple values and comparing objects
When you writeWhat you getWhy
3 === 3trueBoth sides are the number 3.
"tea" === "tea"trueBoth sides are the same text.
firstCart === sameCarttrueBoth names point to one cart.
firstCart === otherCartfalseThese are two carts. Like two mugs that look the same: they are still two mugs.

A reference is the link from a name to an object. When two names share one reference, they share one object. So a change made through one name shows up through the other name too. This matters when you pass a cart, a user, or a settings object to another part of an app.

One cart, two names: a change shows in bothPop out in the code editor (opens in a new tab)JavaScript
const cart = { total: 3 };const savedCart = cart; cart.total = 4;console.log(savedCart.total);

Line 2 makes savedCart point to the same object as cart. Line 4 changes that object's total to 4. Line 5 reads the total through the other name, savedCart, and prints 4. This is not a reason to avoid objects. It is a reason to know which one you need: the same object, or a new one.

Compare the thing you mean

Use === to ask whether two names point to the same object. To check whether two separate objects hold the same contents, compare the parts you care about. For example: firstCart.total === otherCart.total.

Comparing strings

STEP THROUGH

Four more operators also give true or false:

  • < means "less than".
  • > means "greater than".
  • <= means "less than or equal to".
  • >= means "greater than or equal to".

They are called relational operators, because they ask how two values relate: which one comes first? With two numbers, they work like in math class.

With two strings, JavaScript compares the text one character at a time, from the left. Every character has a number, called its character code. For example, "A" is 65 and "a" is 97. The character with the smaller code comes first.

Text order is not number orderPop out in the code editor (opens in a new tab)JavaScript
console.log("tea" < "water");console.log("10" < "9");console.log(Number("10") < Number("9"));

Line 1 prints true, because "t" comes before "w". Line 2 also prints true. Both sides are text, so JavaScript compares the first characters: "1" comes before "9". Line 3 turns both texts into numbers first. Then it asks the number question, "is 10 less than 9?", and prints false.

"10" < "9" as text. JavaScript compares the first characters, "1" and "9". "1" comes first, so the answer is true. The "0" is never needed."10"10"9"9not neededfirst characters"1" < "9"true
JavaScript reads text one character at a time, from the left. The first characters, "1" and "9", are already different, and "1" comes first. So "10" < "9" is true. The "0" is never checked.
Real-life analogyComparing text is like looking up words in a dictionary

Picture a dictionary that puts words in order by the number of each letter. You look at the first letter of two words. If they are the same, you move to the next letter. The first letter that is different decides which word comes first. In this dictionary, every word that starts with a capital letter comes before every word that starts with a small letter.

In real life: Look at the first letter of each word
In JavaScript: Compare the first character of each string
In real life: If they match, look at the next letter
In JavaScript: Compare the next character
In real life: This dictionary puts capital letters first
In JavaScript: Uppercase letters have smaller codes than lowercase letters

Step through the examples below. Pick one of three modes:

  • Strings only: both sides are text. "10" < "9" is true, because "1" comes before "9".
  • Numbers only: both sides are numbers. 10 < 9 is false.
  • String-number pairs: one side is text and one is a number. JavaScript turns the text into a number first, then compares.
Text order and number order
Step 0 of 4Ready
Your turn: follow the blue line

Choose a mode and guess each answer. Then step through the real comparisons.

Running in
  1. script
Next: line 1
console.log("Apple" < "apple");console.log("10" < "9");console.log("a".charCodeAt(0));
CallStoreChangeResultBlue line: runs next. Ran: already executed.
Recent returnsNothing yet. Start with the blue line.
What should the lines compare?

Pick a mode, then guess the answers again. A new mode starts the steps from the beginning.

A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.
Text order is not the order people expect

Look at "item10" and "item9". Text order puts "item10" first, because 1 comes before 9. A person would put item9 first. The later "Comparing & sorting text" lesson shows how to sort text the way people expect.

null & undefined comparisons

STEP THROUGH

null means "empty on purpose". undefined means "no value was given or found". They are two different values. But == has one special rule for them: null == undefined is true.

Here is the tricky part. == and the relational operators (<, >, <=, >=) follow different rules for these two values. You'll step through these three below, so watch them closely:

  • null == 0
  • null >= 0
  • undefined >= 0
Check if a value is missingPop out in the code editor (opens in a new tab)JavaScript
function isMissing(value) {  return value == null;} console.log(isMissing(null));console.log(isMissing(undefined));console.log(isMissing(""));

This is the one place where == is used on purpose. The function isMissing gives back the answer from line 2. That line is true only for null or undefined. Lines 5 to 7 print true, true, and false. So an empty string, "", does not count as missing.

Step through null and undefined
Step 0 of 7Ready
Your turn: follow the blue line

These lines look alike, but == and >= follow different rules. Go one step at a time.

Running in
  1. script
Next: line 1
console.log(null === undefined);console.log(null == 0);console.log(null >= 0);console.log(null > 0);console.log(undefined == 0);console.log(undefined >= 0);
CallStoreChangeResultBlue line: runs next. Ran: already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.
Check for missing first

Don't use <, >, <=, or >= on a value that might be missing. First check if it is missing: if (value == null) return;. Then compare it: value >= 0.

NaN never equals itself

STEP THROUGH

NaN stands for "Not a Number". It is a special number value. You get it when a number calculation fails, like Number("tea"). The Numbers & math lesson showed Number.isNaN(). Here is why you need it: equality can't find NaN.

Left: NaN === NaN gives false, so equality cannot find NaN. Right: Number.isNaN(NaN) gives true, so this check works.NaN === NaNNaNNaNfalseequality failsNumber.isNaN(NaN)NaNtruethis check works
Equality can't find NaN: even NaN === NaN is false. Number.isNaN() asks the question you mean, "is this NaN?", and says true.
Real-life analogyNaN is a sealed mystery box

You have two sealed boxes. Both are marked "unknown". Are the contents the same? You can't tell, so you can't say yes. JavaScript treats NaN the same way. It never says that NaN equals anything, not even another NaN.

In real life: A sealed box marked unknown
In JavaScript: A failed number result, NaN
In real life: Two sealed boxes are never called the same
In JavaScript: NaN === NaN is false
In real life: A scanner made to spot those boxes
In JavaScript: Number.isNaN(value)
Check if turning text into a number failedPop out in the code editor (opens in a new tab)JavaScript
const failedPrice = Number("tea"); console.log(Number.isNaN(failedPrice));console.log(Number.isNaN("tea"));console.log(isNaN("tea"));

Line 1 tries to turn "tea" into a number. That fails, so failedPrice is NaN. Line 3 prints true. Line 4 prints false: "tea" is text, not the value NaN.

Line 5 uses the older isNaN(), without Number. in front. It turns the text into a number first, gets NaN, and prints true. That answer is about the changed value, not about "tea". So use Number.isNaN() instead.

Why equality can't find NaN
Step 0 of 6Ready
Your turn: follow the blue line

Equality can't find NaN. Step through to see which checks can.

Running in
  1. script
Next: line 1
console.log(NaN == NaN);console.log(Number.isNaN(NaN));console.log(Object.is(NaN, NaN));console.log([NaN].includes(NaN));console.log([NaN].indexOf(NaN));
CallStoreChangeResultBlue line: runs next. Ran: already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

The last two lines use arrays, which have their own lesson later. For now, remember one habit: to ask "is this NaN?", write Number.isNaN(value).

Where you’ll use this

Comparisons appear wherever your program picks a path. In front-end code, values often start as text. Text can come from:

  • form fields,
  • parts of a web address (a URL),
  • saved settings,
  • data sent by a server.

Safe code turns that text into the right type where everyone can see it. Then it compares.

A safe age check for a ticket formPop out in the code editor (opens in a new tab)JavaScript
const ageText = "18";const age = Number(ageText); if (Number.isNaN(age)) {  console.log("Please enter a number.");} else if (age >= 18) {  console.log("Adult ticket");} else {  console.log("Child ticket");}

Line 2 turns the text into a number. Line 4 checks if that failed, and asks for a number if so. Only then does line 6 compare the age with >=. Here the age is 18, so it prints Adult ticket.

Use this table when you are not sure which comparison to write. Find what you want to do in the first column. The next columns show what to write and why.

Which comparison to write
When you want toWriteWhy
Check that two values are the samea === bIt checks the type and the value, and changes nothing.
Compare text from a form with a numberNumber(input) === expectedThe change from text to number is easy to see and to test.
Check if a value is null or undefinedvalue == null, or two === checksThis is the one == shortcut that many teams allow.
Check if a number calculation failedNumber.isNaN(value)Equality can't find NaN.
Sort words the way people expectLater: localeCompare or Intl.CollatorPlain < uses character codes, not the rules of a language.

This is also why linters often warn about ==. A linter is a tool that checks your code for common mistakes. It doesn't mean == is useless. It means changes you can't see cause many bugs.

Compare the part of the cart you care aboutPop out in the code editor (opens in a new tab)JavaScript
const savedCart = { total: 3 };const currentCart = { total: 3 }; console.log(savedCart === currentCart);console.log(savedCart.total === currentCart.total);

These are two separate carts, so line 4 prints false. Their totals match, so line 5 prints true. In a real app, compare only the totals if matching totals is really the rule. An order number, the items, or the delivery address might matter too.

Common misconceptions

“== and === are basically the same.”

They only agree when no conversion happens. "0" == 0 is true, but "0" === 0 is false.

“= compares values.”

= stores a value. It puts the value on the right into the name on the left. To compare, use === or ==.

“String order is the same as dictionary order.”

Plain string comparison uses character codes. Uppercase letters come before lowercase letters. And "10" comes before "9".

“null >= 0 and null == 0 should match.”

They follow different rules. >= turns null into 0, so null >= 0 is true. == has its own rule for null: it only equals undefined. So null == 0 is false.

“Use x === NaN to find failed numbers.”

That comparison is always false. Use Number.isNaN(x).

Sort the comparison habits
  • score === 10
  • Number(input) === 5
  • Number.isNaN(total)
  • value == null
  • input == 5
  • result === NaN
Try it yourself
0 of 6 correct

Put each piece of code in a group. Each card explains why it belongs there.

Choose a category for every card. You can change an answer at any time; Reset clears them all.

Practice: comparisons

6 EXERCISES

Try each one before you open the hints. Every output was checked by running real JavaScript.

Exercise 1 · Warm-upPredict four comparisons

Predict the four outputs, in order.

Starter codePop out in the code editor (opens in a new tab)JavaScript
console.log("0" == 0);
console.log("0" === 0);
console.log(null == undefined);
console.log(NaN === NaN);

Answer, then press Check. Spacing and letter case don’t matter.

    Exercise 2 · PracticeFix the hidden text-to-number bug

    This code unlocks level 5, but entered is text. == quietly changes it into a number. Rewrite it: turn the text into a number yourself, then compare with ===.

    Starter codePop out in the code editor (opens in a new tab)JavaScript
    const entered = "5";
    
    if (entered == 5) {
      console.log("Level 5 unlocked");
    }

    Answer, then press Check. Spacing and letter case don’t matter.

      Exercise 3 · PracticePredict the text order

      Predict the three outputs. This surprise is why a later lesson teaches other ways to sort text.

      Starter codePop out in the code editor (opens in a new tab)JavaScript
      console.log("item10" < "item9");
      console.log("10" < "9");
      console.log(10 < 9);

      Answer, then press Check. Spacing and letter case don’t matter.

        Exercise 4 · ChallengeWrite an isMissing check

        Write the expression after return. It should be true only for null or undefined.

        Starter codePop out in the code editor (opens in a new tab)JavaScript
        function isMissing(value) {
          return value == null;
        }
        console.log(isMissing(null));
        console.log(isMissing(undefined));
        console.log(isMissing(0));

        Answer, then press Check. Spacing and letter case don’t matter.

          Exercise 5 · ChallengeFind a NaN result

          Turning text into a number failed. What should you write to check that the result is NaN?

          Starter codePop out in the code editor (opens in a new tab)JavaScript
          const value = Number("nope");
          console.log(Number.isNaN(value));

          Answer, then press Check. Spacing and letter case don’t matter.

            Exercise 6 · ChallengeCompare two cart totals

            A checkout page should show a message only when two carts have the same total. What should go inside the brackets of the if?

            Starter codePop out in the code editor (opens in a new tab)JavaScript
            const savedCart = { total: 3 };
            const currentCart = { total: 3 };
            
            if (savedCart.total === currentCart.total) {
              console.log("Same total");
            }

            Answer, then press Check. Spacing and letter case don’t matter.

              Quiz: check your understanding

              8 QUESTIONS

              Your score counts first tries. Read every explanation. The wrong choices are common comparison bugs.

              Lesson quiz · 8 questionsScore: first tries count
              1. Question 1 of 8Which operator should you use to check if two values are equal?

                Choose an answer to see the explanation.

              2. Question 2 of 8What does this loose equality check print?

                Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
                console.log("5" == 5);

                Choose an answer to see the explanation.

              3. Question 3 of 8What does this text comparison print?

                Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
                console.log("Apple" < "apple");

                Choose an answer to see the explanation.

              4. Question 4 of 8What does null >= 0 print?

                Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
                console.log(null >= 0);

                Choose an answer to see the explanation.

              5. Question 5 of 8What does undefined >= 0 print?

                Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
                console.log(undefined >= 0);

                Choose an answer to see the explanation.

              6. Question 6 of 8Which expression correctly checks if a value is NaN?

                Choose an answer to see the explanation.

              7. Question 7 of 8What does includes print for NaN?

                Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
                console.log([NaN].includes(NaN));

                Choose an answer to see the explanation.

              8. Question 8 of 8What does === print for two carts made separately with the same total?

                Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
                console.log({ total: 3 } === { total: 3 });

                Choose an answer to see the explanation.

              Key takeaways

              • Use === to check if two values are equal. It checks the type and the value.
              • == may change a value before it compares. Use it only on purpose, mostly as value == null.
              • For objects, === asks if both names point to the same object. To check the contents, compare the parts you need.
              • Text is compared by character codes. So capital letters, and text like "10", can surprise you.
              • Check if a value is missing before you use <, >, <=, or >=.
              • NaN never equals itself. Use Number.isNaN(value).

              Remember the one-liner.
              Compare with ===, turn values into the right type yourself, and use special checks for null and NaN.

              Coming next: Logical operators.

              CompleteFrontend Clear concepts. Working examples.