I recently had a conversation with Scoot Koon (LazyCoder) over Twitter about the wacky JavaScript type comparisons that are allowed. I was interested to see what weird oddities would come out if I compared the whole type system against it self. So I sat down and wrote a simple JavaScript routine to do just that, and the below reference table is the output of that routine.
| null | undefined | true | false | -1 | 0 | 1 | NaN | Infinity | “” | ” “ | “null” | “undefined” | “true” | “false” | “-1″ | “0″ | “1″ | “NaN” | “Infinity” | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| null | null | null | – | – | – | – | – | – | – | – | – | – | – | – | – | – | – | – | – | – |
| undefined | undefined | undefined | – | – | – | – | – | – | – | – | – | – | – | – | – | – | – | – | – | – |
| true | – | – | true | – | – | – | true | – | – | – | – | – | – | – | – | – | – | true | – | – |
| false | – | – | – | false | – | false | – | – | – | false | false | – | – | – | – | – | false | – | – | – |
| -1 | – | – | – | – | -1 | – | – | – | – | – | – | – | – | – | – | -1 | – | – | – | – |
| 0 | – | – | – | 0 | – | 0 | – | – | – | 0 | 0 | – | – | – | – | – | 0 | – | – | – |
| 1 | – | – | 1 | – | – | – | 1 | – | – | – | – | – | – | – | – | – | – | 1 | – | – |
| NaN | – | – | – | – | – | – | – | – | – | – | – | – | – | – | – | – | – | – | – | – |
| Infinity | – | – | – | – | – | – | – | – | Infinity | – | – | – | – | – | – | – | – | – | – | Infinity |
| “” | – | – | – | “” | – | “” | – | – | – | “” | – | – | – | – | – | – | – | – | – | – |
| ” “ | – | – | – | ” “ | – | ” “ | – | – | – | – | ” “ | – | – | – | – | – | – | – | – | – |
| “null” | – | – | – | – | – | – | – | – | – | – | – | “null” | – | – | – | – | – | – | – | – |
| “undefined” | – | – | – | – | – | – | – | – | – | – | – | – | “undefined” | – | – | – | – | – | – | – |
| “true” | – | – | – | – | – | – | – | – | – | – | – | – | – | “true” | – | – | – | – | – | – |
| “false” | – | – | – | – | – | – | – | – | – | – | – | – | – | – | “false” | – | – | – | – | – |
| “-1″ | – | – | – | – | “-1″ | – | – | – | – | – | – | – | – | – | – | “-1″ | – | – | – | – |
| “0″ | – | – | – | “0″ | – | “0″ | – | – | – | – | – | – | – | – | – | – | “0″ | – | – | – |
| “1″ | – | – | “1″ | – | – | – | “1″ | – | – | – | – | – | – | – | – | – | – | “1″ | – | – |
| “NaN” | – | – | – | – | – | – | – | – | – | – | – | – | – | – | – | – | – | – | “NaN” | – |
| “Infinity” | – | – | – | – | – | – | – | – | “Infinity” | – | – | – | – | – | – | – | – | – | – | “Infinity” |
So some of the oddities that emerged to me are:
- The word “Infinity” is equal to the type
Infinity, however “true” or “false” don’t equaltrueorfalserespectively. " " == 0 == falseand also"" == 0 == false, however" " != ""- Update Just noticed that
NaN != NaNbutInfinity == Infinity
If you would like to try this your self, or want to add to it, here is the code that I used.
var values = [null, undefined, true, false, -1, 0, 1, NaN, Infinity, "", " ", "null", "undefined", "true", "false", "-1", "0", "1", "NaN", "Infinity"];
document.write("<table><thead><tr><th></th>")
for (var x = 0; x < values.length; x++) {
document.write("<th>" + (x > 8 ? """ : "") + values[x] + (x > 8 ? """ : "") + "</th>");
}
document.write("</tr></thead><tbody>");
for (var i = 0; i < values.length; i++) {
document.write("<tr>");
document.write("<th>" + (i > 8 ? """ : "") + values[i] + (i > 8 ? """ : "") + "</th>");
for (var j = 0; j < values.length; j++) {
var output = values[i] == values[j];
document.write("<td style="text-align:center;" + (i == j ? "background-color:black;" : (output ? "background-color:green;color:#00AF33;" : "color:#e0e0e0;")) + "">");
document.write(output ? (i > 8 ? """ : "") + values[i] + (i > 8 ? """ : "") : "--");
document.write("</td>");
}
document.write("</tr>");
}
document.write("</tbody></table>");
I think Scott really hit the nail on the head when he said this about JavaScript coercion.
JavaScript


That’s one of the main reasons why I always use ===, !==, etc. for comparisons. To explicitly prohibit type coercion when comparing values or objects and avoid those “WTF” moments (or at least, avoid them most of the time.)
Humm, should you not have been using the Javascript equality test (===) instead of ==?
David and David,
The point of this wasn’t that I didn’t know about === or !==, it was the wacky way that non-specific type comparisons happen in JavaScript. This post is suppose to be a reference sheet of the non-type specific comparisons available in JavaScript. Because sometimes they can be great to compare a “0″ against a 0, or a 0 against a false. I do know about type specific comparisons in JavaScript and I use them when necessary.
It would be interesting to see the differences (if any) between browsers!
Ok, I can understand null==undefined. Type coercion, undefined is casted to null, you should really use === if you want to distinguish between them. But can anybody explain for me the twisted logic behind 0==”"? Why 0 is not casted to string first?