JavaScript's Abstract Equality Algorithm: Why == Produces Surprising Results

Open a browser console and type these four lines:

"" == 0;        // true
"0" == 0;       // true
"" == "0";      // false
[] == ![];      // true

If the first three results make you uneasy, you are noticing something real. Loose equality in JavaScript is not transitive, so a == b and b == c do not guarantee a == c. The fourth line looks like a bug in the language, yet it follows directly from a published algorithm.

That algorithm is what this guide covers. By the end you will be able to predict the result of any == comparison by hand, explain why the odd results happen, and decide when == is acceptable and when to use something else.

Quick Answer

The == operator runs the abstract equality algorithm. The current ECMAScript specification calls it IsLooselyEqual. If both operands have the same type, it behaves exactly like ===. If the types differ, it converts one or both operands, following a fixed sequence of rules, until the types match. It then compares them. Most surprises come from those conversions, especially booleans and objects being turned into numbers or strings.

What "Abstract Equality" Actually Means