Knowledge Base/concepts/JavaScript Comparison Operators

JavaScript Comparison Operators

JavaScript comparison operators do one job: they turn a question into true or false. That sounds tiny until the question is slightly wrong. age >= 18 is a clear rule. value == 0 is an invitation for JavaScript to guess what you meant, and JavaScript guesses with the confidence of someone who has never had to maintain your code.

The useful habit is not memorizing every weird comparison. It is choosing the operator that matches the rule you actually need.

The comparison operators

Most day-to-day comparisons use these operators:

OperatorMeaningExample
===strictly equalstatus === "paid"
!==strictly not equalrole !== "guest"
>greater thanscore > 90
<less thanstock < 1
>=greater than or equal toage >= 18
<=less than or equal toattempts <= 3

Each expression returns a boolean:

const age = 19;
const hasEnoughAge = age >= 18;

console.log(hasEnoughAge); // true
console.log(typeof hasEnoughAge); // "boolean"

That boolean is what an if, ternary, &&, or || expression can use next.

Use strict equality by default

Strict equality, ===, checks both value and type:

5 === 5; // true
"5" === 5; // false
false === 0; // false

Loose equality, ==, allows type coercion first:

"5" == 5; // true
false == 0; // true
"" == 0; // true

That can look helpful in a tiny example. In real code, it hides bugs. If a form field gives you "5" and your app expects the number 5, convert the value intentionally:

const rawQuantity = "5";
const quantity = Number(rawQuantity);

if (quantity === 5) {
  console.log("Five items");
}

The conversion is now visible. A future reader does not have to wonder whether the string was accepted on purpose.

Relational comparisons check order

The relational operators compare whether one value is above or below another:

const subtotal = 48;

const qualifiesForDiscount = subtotal >= 50;
const needsMinimumWarning = subtotal < 50;

console.log(qualifiesForDiscount); // false
console.log(needsMinimumWarning); // true

The equality part matters. > and < exclude the boundary. >= and <= include it.

const age = 18;

age > 18; // false
age >= 18; // true

That small choice is a business rule. An age gate, a shipping threshold, or a retry limit can be wrong by one value if the boundary is careless.

Naive checks fail at the boundary

This looks reasonable at first:

function canBuyTicket(age) {
  return age > 18;
}

console.log(canBuyTicket(18)); // false

If the rule is "18 or older," the operator is wrong. The corrected version includes the boundary:

function canBuyTicket(age) {
  return age >= 18;
}

console.log(canBuyTicket(18)); // true

Do not read comparison operators as decoration. Read them as the exact policy your code is enforcing.

String comparisons are alphabetical, not numeric

Strings can be compared with relational operators:

"apple" < "banana"; // true
"zebra" > "ant"; // true

That comparison uses lexicographic order, roughly dictionary order based on character codes. It is useful for sorting labels, but it can surprise you when numeric-looking strings are involved:

"20" > "100"; // true

As strings, "2" comes after "1", so "20" sorts after "100". If the values are numbers, compare numbers:

Number("20") > Number("100"); // false

Again, the fix is intentional conversion before comparison.

Objects compare by identity

Objects and arrays are compared by reference, not by matching contents:

const first = { id: 1 };
const second = { id: 1 };
const same = first;

first === second; // false
first === same; // true

first and second look alike, but they are two different objects. same points to the exact same object as first.

The same rule applies to arrays:

[1, 2, 3] === [1, 2, 3]; // false

If you need to compare object contents, compare the specific fields that matter:

const selectedUser = { id: "u_123", name: "Ada" };
const currentUser = { id: "u_123", name: "Ada Lovelace" };

const isSameUser = selectedUser.id === currentUser.id;

console.log(isSameUser); // true

That is usually better than asking JavaScript whether two entire objects are "the same." Your app probably cares about one identifier, not every property.

NaN is not equal to itself

NaN means "not a number," usually from a failed numeric operation:

const result = Number("not a price");

console.log(result); // NaN
console.log(result === NaN); // false

That last line feels rude, but it is standard JavaScript behavior. Use Number.isNaN:

const result = Number("not a price");

if (Number.isNaN(result)) {
  console.log("Invalid number");
}

This is one of the few cases where strict equality is not the right tool.

Comparisons inside conditions

Comparison operators become useful when they drive a decision:

const attempts = 2;
const maxAttempts = 3;

if (attempts < maxAttempts) {
  console.log("Try again");
} else {
  console.log("Locked");
}

For more than one rule, combine comparisons with JavaScript logical operators:

const age = 16;
const hasGuardianApproval = true;

const canAttend = age >= 13 && (age >= 18 || hasGuardianApproval);

console.log(canAttend); // true

The comparison operators create the smaller booleans. The logical operators combine them into the full rule.

Comparisons and truthy values are different checks

This condition checks truthiness:

if (discount) {
  console.log("Discount exists");
}

That excludes 0, "", null, undefined, false, and NaN. Sometimes that is fine. Sometimes it is too broad.

If 0 is a valid discount, check for the missing values directly:

if (discount !== null && discount !== undefined) {
  console.log(`Discount: ${discount}`);
}

For the broader coercion rules, read Truthy and Falsy Values in JavaScript.

Key Takeaways

  • Comparison operators return booleans, which are the raw material for conditions.
  • Use === and !== by default so JavaScript does not quietly coerce types.
  • Choose > versus >= by the real boundary rule, not by habit.
  • Strings compare by character order, so convert numeric text before numeric comparisons.
  • Objects compare by identity. Compare meaningful fields when contents matter.
Share this article:
javascriptfundamentalsoperatorsconditionals