This post explains how javascript does when it compares two values with a relational operator ( <, >, <=, >=). If you are looking for equality comparison ( ==, ===), check this post instead.


Abstract Relational Comparison algorithm

The relation comparison in Javascript mainly follows the Abstract Relational Comparison algorithm, described in the ECMA specs. The less than ( <) operator works as follows:

  • Step 1: if any of the the operands is not primitive, convert them to primitives, using operand[Symbol.toPrimitive]('number').
  • Step 2: If both are string type, compare them lexicographically. Finish the algorithm.
  • Step 3: If one of the operands is a string, and the other one is a BigInt. Convert the string value to BigInt with BigInt(value).
  • Step 4: apply several following conversions (apply the ToNumber Conversions table unless the value is a BigInt).
Operand value Converted value
undefined NaN
null +0
true 1
false 0
number value unchanged
BigInt value unchanged (toNumeric)
string value parseFloat(value)
Symbol value throw a TypeError
  • Step 5: If either value is NaN, return false. Otherwise, compare two values in the numeric order.

Example 1

This is a demonstration example on date objects' comparisons.

new Date(2020, 0, 1) < new Date(2020, 8, 13) // returns true
new Date(2020, 0, 1)[Symbol.toPrimitive]('number') // returns 1577804400000
new Date(2020, 8, 13)[Symbol.toPrimitive]('number') // returns 1599922800000
  • Step 5: 1577804400000 less than 1599922800000 by their numerical order. The operator gives true as the result.

Longer explanation


Example 2

new Date(2020, 0, 1) < 'a' // return false
'a' < new Date(2020, 0, 1) // return false
  • Step 1: similar to the example 1.
  • Step 4: 'a' is converted with parseFloat('a') and becomes NaN.
  • Step 5: return false in either cases.

Example 3

new Date(2020, 0, 1) < 'Infinity' // return true
'Infinity' < new Date(2020, 0, 1) // return false
  • Similar to the example 2, except that parseFloat('Infinity') is evaluated to be Infinity.