10

What rules apply for the JavaScript relational comparison operators when the operands are of different types?

For example, how is true > null evaluated? I can type this into my developer console and it gives the result true, but why?

I searched for a bit, but didn't find any blog posts explaining this, although there are plenty explaining type coercion for == and === comparison operators.

Caspar
  • 7,039
  • 4
  • 29
  • 41
  • 1
    Dear downvoters, please note that StackOverflow [explicitly encourages asking and answering your own questions](http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/), so I would appreciate some feedback explaining why my question is receiving downvotes while my answer is receiving upvotes :-) – Caspar Feb 04 '13 at 13:40
  • 3
    Your answer is quite good. Your question... not so much. Remember, self-answered questions are indeed encouraged but getting the question part right is *hard*. If your question is not of outstanding quality and is not marked community wiki, it may well be downvoted or even closed. See http://meta.stackexchange.com/questions/163623/what-can-i-do-to-improve-the-question-portion-of-a-self-answered-android-debuggi for examples of what you can do to curb this. – Frédéric Hamidi Feb 04 '13 at 13:47
  • im not gonna downvote, YET, i want to see your answer to this: how you make such question and less than 1 min later you give a detailed and complete answer? You really had the doubt? – Toping Feb 04 '13 at 13:49
  • I'm not one of the downvoters, but I believe the question is too generic. It's a little better after the edit, and can now be read as a request for an explanation of the `null > true` case. That's more Stack Overflow-ish. – bfavaretto Feb 04 '13 at 13:51
  • @Ark, that doesn't really matter, you can post questions that you already know the answer to. The quality of the question, however, is paramount here. – Frédéric Hamidi Feb 04 '13 at 13:51
  • @Ark there's actually a specific option when you ask a question to answer it straight away as well – Caspar Feb 04 '13 at 14:04

1 Answers1

23

JavaScript relational comparison operator type coercion is defined in the JavaScript specification, specifically in sections 11.8 to 11.8.5 which describe the operators, and sections 9.1 (ToPrimitive) and 9.3 (ToNumber) which describe the process of coercing the operands.

In short, the 4 comparison operators (<, >, <=, and >=) do their best to convert each operand to a number, then compare the numbers. The exception is when both operands are strings, in which case they are compared alphabetically.

Specifically,

  1. If an argument o is an object instead of a primitive, try to convert it to a primitive value by calling o.valueOf() or - if o.valueOf wasn't defined or didn't return a primitive type when called - by calling o.toString()

  2. If both arguments are Strings, compare them according to their lexicographical ordering. For example, this means "a" < "b" and "a" < "aa" both return true.

  3. Otherwise, convert each primitive to a number, which means:

    • undefined -> NaN
    • Null -> +0
    • Boolean primitive type -> 1 if true, +0 if false
    • String -> try to parse a number from the string
  4. Then compare each item as you'd expect for the operator, with the caveat that any comparison involving NaN evaluates to false.

So, this means the following:

console.log(true > null);           //prints true
console.log(true > false);          //prints true
console.log("1000.0" > 999);        //prints true
console.log("  1000\t\n" < 1001);   //prints true

var oVal1 = { valueOf: function() { return 1; } };
var oVal0 = { toString: function() { return "0"; } };

console.log(oVal1 > null);         //prints true
console.log(oVal0 < true);         //prints true
console.log(oVal0 < oVal1);        //prints true
Caspar
  • 7,039
  • 4
  • 29
  • 41