The Abstract Relational Comparison Algorithm

Let’s take the first check.

null > 0; // false

According to the Spec, the relational operators > and < send the statement through an algorithm called the Abstract Relational Comparison Algorithm to find out if the statement is true or false .

1. Call ToPrimitive(x, hint Number). 2. Call ToPrimitive(y, hint Number). 3. If Type(Result(1)) is String and Type(Result(2)) is String, go to step 16. (Note that this step differs from step 7 in the algorithm for the addition operator + in using 'and' instead of 'or'.) 4. Call ToNumber(Result(1)). 5. Call ToNumber(Result(2)). 6. If Result(4) is NaN, return undefined. 7. If Result(5) is NaN, return undefined. 8. If Result(4) and Result(5) are the same number value, return false. 9. If Result(4) is +0 and Result(5) is -0, return false. 10. If Result(4) is -0 and Result(5) is +0, return false. 11. If Result(4) is +∞, return false. 12. If Result(5) is +∞, return true. 13. If Result(5) is -∞, return false. 14. If Result(4) is -∞, return true. 15. If the mathematical value of Result(4) is less than the mathematical value of Result(5) --- note that these mathematical values are both finite and not both zero --- return true. Otherwise, return false. 16. If Result(2) is a prefix of Result(1), return false. (A string value p is a prefix of string value q if q can be the result of concatenating p and some other string r. Note that any string is a prefix of itself, because r may be the empty string.) 17. If Result(1) is a prefix of Result(2), return true. 18. Let k be the smallest nonnegative integer such that the character at position k within Result(1) is different from the character at position k within Result(2). (There must be such a k, for neither string is a prefix of the other.) 19. Let m be the integer that is the code point value for the character at position k within Result(1). 20. Let n be the integer that is the code point value for the character at position k within Result(2). 21. If m < n, return true. Otherwise, return false.

Let’s walk through this algorithm with our statement - null > 0 .

Steps 1 and 2 ask us to call ToPrimitive() on null and 0 respectively to convert these values to their primitive value types (such as Number and String ). The ToPrimitive conversion follows this table.

Going by the table, both our LHS, null , and RHS, 0 , don’t undergo any conversion.

Now Step 3 does not apply to us, so we can ignore it and move on. At Steps 4 and 5, we need to convert both the LHS and RHS to type Number . The conversion to Number follows this table.

(I’ve omitted String and Object from the table as they have a more elaborate conversion, and the conversions are not relevant to us right now anyway. If you are curious about those, you can find them here.) 🙃

null gets converted to +0 and 0 remains 0 . Neither of the values are NaN so we can skip Steps 6 and 7. It’s at Step 8 that we need to stop. +0 is equal to 0 , and the algorithm returns false . Hence,