The problematic operators are the relational operators ('==', '<', '>', '<=', '=>') and the concatenation operator ('+') which is also used for addition. All these operators work with more than one type.
Since some types such as some objects can be converted to either Numbers or Strings, the conversion rules for these hard cases come down to describing which way the two arguments will be converted in which circumstances. All else being equal, arguments that are Objects have a preference which of String or Number they will convert to (usually Number, except for the Date type), and that preference can figure in the conversion decision as well.
The easiest case to understand is '+', the addition/concatenation operator. The rule is:
For + operators, if either argument is a String or converts preferentially to one, then do String concatenation, not addition. Otherwise, neither argument prefers to be a String so do Number addition.
To apply this test to a specific example ask yourself: would either argument like to be a String? If so, concatenation is in order. The interpreter does the same thing.
For the relational operators, the situation is similar but the case for Strings is 'weaker'.
For >, >=, <, <= operators, if neither argument can be converted to a Number, then do string comparison, not numeric comparison. Otherwise, at least one argument can be converted to a Number, so do numeric comparison.
To apply this test to a specific example, ask yourself: could either argument be a Number? If so, numeric comparison is in order. The interpreter does the same thing.
Remembering what happens in these two cases can be tricky because it can go either way (Number or String), and it's all a bit obscure. A memory trick that will acts as rough guide is to remember this:
"String plus: either String, String compare: neither Number"
The case of inequality and equality is different again:
For ==, != operators, first convert any Objects to their preferred primitive types. If the types are still different, convert any Boolean to a Number. If the types are still different, convert the non-Number argument to Number and compare as Numbers. Exception: null == undefined without any conversion required.
To apply this test to a specific example, ask yourself: would both arguments prefer to be Strings? If so, a string equality test is in order, otherwise it's a numeric equality test.
These ECMAScript comparison rules all roughly agree with the pre-ECMAScript versions of JavaScript currently available. There is one particular trap to be wary of.
Netscape's JavaScript version 1.2 abandons most of the type conversion rules, incorrectly anticipating the standard. This means "3" != 3, for example. Fortunately, if you don't explicitly ask for this version of JavaScript when you embed your script in a Web page, it works like the older versions of JavaScript that both the standard and Internet Explorer are closer to. Even more fortunately, in Netscape Navigator 4.0 if you don't explicitly request the 1.2 version, you still have access to all the 1.2 features, except for this specific change.
and ===
have been proposed for inclusion in the standard to support this variation. Internet Explorer 4.0 supports these operators.!==
It's also true that bugs in the Microsoft and Netscape implementations make some of the more subtle comparisons unreliable. Early versions get easily confused about comparisons with NaN, null and 0 when type conversions are involved.