# 11.9.3 Equality comparison algorithm

2010-05-17

Code: (Meta Ecma)
`function EqualityComparison(x, y) { if (Type(x) == Type(y)) { if (Type(x) == 'undefined') return true; if (Type(x) == 'null') return true; if (Type(x) == 'number') { // nan never matches anything if (isNaN(x)) return false; if (isNaN(y)) return false; // zeroes match (unlike SameValue) if (x === -0 && y === +0) return true; if (x === +0 && y === -0) return true; // now just check values return x == y; // note that the specification checks number // values first, zeroes later, then returns false. } if (Type(x) == 'string') return x == y; if (Type(x) == 'boolean') return x == y; // x and y are objects... return x == y; // "refer to same object" } // x and y are not same type: coerce one // undefined equals null if (x === null && y === undefined) return true; if (x === undefined && y === null) return true; // if comparing number to string, coerce to number if (Type(x) == 'number' && Type(y) == 'string') return x == ToNumber(y); if (Type(x) == 'string' && Type(y) == 'number') return ToNumber(x) == y; // if bool to number, coerce to number if (Type(x) == 'boolean' && Type(y) == 'number') return ToNumber(x) == y; if (Type(x) == 'number' && Type(y) == 'boolean') return x == ToNumber(y); // string or number to object, coerce object to primitive and try again if ((Type(x) == 'string' || Type(x) == 'number') && Type(y) == 'object') return x == ToPrimitive(y); if (Type(x) == 'object' && (Type(y) == 'string' || Type(y) == 'number')) return ToPrimitive(x) == y; // i'm not sure what could trickle down past here, but it returns false :) return false;}`
String comparison can be forced by a+'' == b+''. Number comparison by +a == +b. Boolean by !a == !b.

The following holds:
(A != B) === !(A==B)
(A==B) === (B==A) (except in the order of evaluation, which "can" be observed, but usually isn't)

Transitivity (if a==b and b==c then a==c) doesn't always hold due to coercion. A string object will match with a string literal with the same value, but not with another string object with the same value.

String comparison is simple, based on Unicode code point values. Strings that would canonically (after evaluation) match will not match using the equality comparison, unless they were the same string before evaluation.

I've written a tool which might help you in discovering the steps taken when coercion is applied. You can find it on jscoercion.qfox.nl :)