javascript-today

Comparison Operators

Comparison operators let you compare values and return true or false. They’re essential for making decisions in your code with conditionals and loops.

What are Comparison Operators?

Operators that compare two values and return a boolean (true or false):

5 > 3      // true
10 === 10  // true
'hello' !== 'world'  // true

These results are used in if statements, while loops, and anywhere you need to check conditions.

Equality Operators

Strict Equality (===)

Checks if values are equal and the same type:

5 === 5           // true (same value, same type)
5 === '5'         // false (same value, different type)
'hello' === 'hello'  // true
true === true     // true
null === null     // true

Use this most of the time! It’s predictable and safe.

Loose Equality (==)

Checks if values are equal after type conversion:

5 == 5            // true
5 == '5'          // true (converts '5' to number)
true == 1         // true (converts true to 1)
false == 0        // true (converts false to 0)
'' == 0           // true (converts '' to 0)

Avoid this! It can cause confusing bugs.

The Difference

// Strict equality (===)
5 === '5'         // false (number vs string)
0 === false       // false (number vs boolean)
null === undefined // false (different types)

// Loose equality (==)
5 == '5'          // true (converts string to number)
0 == false        // true (converts both to number)
null == undefined // true (special case)

Best Practice: Always use === unless you have a specific reason not to.

Inequality Operators

Strict Inequality (!==)

Opposite of ===:

5 !== 3           // true
5 !== 5           // false
5 !== '5'         // true (different types)
'hello' !== 'world'  // true

Loose Inequality (!=)

Opposite of ==:

5 != 3            // true
5 != '5'          // false (converts '5' to number 5)

Recommendation: Use !== for consistency with ===.

Relational Operators

Compare numerical or alphabetical order:

Greater Than (>)

10 > 5            // true
5 > 10            // false
5 > 5             // false (not greater, equal)

'b' > 'a'         // true (alphabetical)
'hello' > 'goodbye'  // true (compares first letter)

Greater Than or Equal (>=)

10 >= 5           // true
5 >= 5            // true (equal counts)
3 >= 5            // false

'b' >= 'a'        // true
'a' >= 'a'        // true

Less Than (<)

5 < 10            // true
10 < 5            // false
5 < 5             // false

'a' < 'b'         // true

Less Than or Equal (<=)

5 <= 10           // true
5 <= 5            // true
10 <= 5           // false

'a' <= 'a'        // true

Comparing Different Types

Numbers

100 > 50          // true
-5 < 0            // true
3.14 >= 3         // true

// Edge case: comparing to NaN always returns false
NaN === NaN       // false
NaN > 5           // false
NaN < 5           // false

Strings

Compared alphabetically (lexicographically):

'apple' < 'banana'   // true (a comes before b)
'zebra' > 'apple'    // true (z comes after a)
'Apple' < 'apple'    // true (uppercase < lowercase in ASCII)

// Comparing character by character
'cat' < 'catch'      // true (shorter string comes first)
'10' < '2'           // true (string comparison, not numeric!)

String vs Number Comparison

// With loose equality (==)
'5' == 5          // true (string converted to number)
'10' < 20         // true (string converted to number)

// With strict equality (===)
'5' === 5         // false (different types)

// Be careful!
'10' > '2'        // false (string comparison)
10 > 2            // true (number comparison)

Boolean Comparisons

true === true     // true
true === false    // false
true > false      // true (true converts to 1, false to 0)

// Comparisons with other types (loose equality)
true == 1         // true
false == 0        // true
true == 'true'    // false

null and undefined

null === null          // true
undefined === undefined  // true
null === undefined     // false (different types)

null == undefined      // true (special case in loose equality)

null > 0              // false
null >= 0             // true (quirk!)
null == 0             // false

Common Patterns

1. Range Checking

const age = 25;

if (age >= 18 && age < 65) {
  console.log('Working age adult');
}

const score = 85;

if (score >= 0 && score <= 100) {
  console.log('Valid score');
}

2. Input Validation

const password = 'myPassword123';

if (password.length >= 8) {
  console.log('Password is long enough');
} else {
  console.log('Password must be at least 8 characters');
}

const quantity = 5;
const maxQuantity = 10;

if (quantity <= maxQuantity) {
  console.log('Order accepted');
} else {
  console.log('Exceeds maximum quantity');
}

3. Checking Empty Values

const username = '';

if (username === '') {
  console.log('Username is required');
}

// Or check length
if (username.length === 0) {
  console.log('Username is required');
}

const items = [];

if (items.length === 0) {
  console.log('No items in cart');
}

4. Comparing User Input

const userAnswer = 'Paris';
const correctAnswer = 'Paris';

if (userAnswer === correctAnswer) {
  console.log('Correct!');
} else {
  console.log('Wrong answer');
}

// Case-insensitive comparison
if (userAnswer.toLowerCase() === correctAnswer.toLowerCase()) {
  console.log('Correct!');
}

5. Finding Min/Max

const price1 = 29.99;
const price2 = 19.99;

if (price1 < price2) {
  console.log('Price 1 is cheaper');
} else if (price2 < price1) {
  console.log('Price 2 is cheaper');
} else {
  console.log('Prices are equal');
}

Special Cases

Comparing Objects and Arrays

// Objects and arrays are compared by reference, not value
const arr1 = [1, 2, 3];
const arr2 = [1, 2, 3];
const arr3 = arr1;

arr1 === arr2     // false (different objects in memory)
arr1 === arr3     // true (same reference)

const obj1 = { name: 'Alice' };
const obj2 = { name: 'Alice' };

obj1 === obj2     // false (different objects)

To compare values, compare properties:

const obj1 = { name: 'Alice' };
const obj2 = { name: 'Alice' };

obj1.name === obj2.name  // true

Comparing with undefined and null

let x;
x === undefined   // true (x is undefined)

let y = null;
y === null        // true

// Be careful with comparisons
undefined == null     // true (loose equality special case)
undefined === null    // false (different types)

Type Conversion in Comparisons

// Numbers from strings
'10' > 5          // true (string '10' converted to number 10)
'5' < 10          // true

// Be careful with leading zeros
'05' == 5         // true (converted to number)

// Booleans to numbers
true > 0          // true (true becomes 1)
false < 1         // true (false becomes 0)

Best Practices

DO:

  • Use === and !== for equality checks
  • Be explicit in comparisons
  • Consider edge cases (null, undefined, NaN)
  • Use parentheses for clarity in complex comparisons
// Good
if (age === 18) { }
if (score >= 60) { }
if (name !== '') { }

// Clear with parentheses
if ((age >= 18 && age < 65) || isRetired) { }

DON’T:

  • Use == or != unless you need type coercion
  • Compare different types without understanding conversion
  • Forget that NaN !== NaN
  • Compare objects directly for value equality
// Bad
if (age == '18') { }  // Use === instead

// Bad - comparing different types
if ('5' > 3) { }      // Confusing

// Bad - object comparison
if ([1,2] === [1,2]) { }  // Always false

// Bad - NaN comparison
if (result === NaN) { }   // Use isNaN(result) instead

Common Mistakes

1. Assignment vs Comparison

// Wrong - assigns 5 to x (always true)
if (x = 5) {
  console.log('This always runs!');
}

// Correct - compares x to 5
if (x === 5) {
  console.log('x is 5');
}

2. String Number Comparison

// Wrong - string comparison
if ('10' > '2') {
  console.log('10 is greater');
} else {
  console.log('2 is greater'); // This runs! (string '2' > '1')
}

// Correct - convert to numbers
if (Number('10') > Number('2')) {
  console.log('10 is greater'); // This runs
}

3. Using == Instead of ===

// Unexpected results with ==
0 == false        // true
'' == false       // true
null == undefined // true

// Clear results with ===
0 === false       // false
'' === false      // false
null === undefined // false

Checking for NaN

const result = 0 / 0;  // NaN

// Wrong
if (result === NaN) { }  // Never true

// Correct
if (isNaN(result)) {
  console.log('Result is not a number');
}

// Or (modern)
if (Number.isNaN(result)) {
  console.log('Result is not a number');
}

Summary

Operator Meaning Example Result
=== Strict equal 5 === 5 true
!== Strict not equal 5 !== '5' true
> Greater than 10 > 5 true
>= Greater or equal 5 >= 5 true
< Less than 5 < 10 true
<= Less or equal 5 <= 5 true
== Loose equal 5 == '5' true ⚠️
!= Loose not equal 5 != '5' false ⚠️

Key Takeaways:

  • Always use === and !== for predictable comparisons
  • Strings are compared alphabetically
  • NaN is never equal to anything (including itself)
  • Objects and arrays are compared by reference