-
-
Save mde/1013691 to your computer and use it in GitHub Desktop.
js> isNaN(null); | |
false | |
js> null > -1; | |
true | |
js> null < 1; | |
true | |
js> null > 0; | |
false | |
js> null < 0; | |
false | |
js> null == 0; | |
false |
Right, it all made sense to me until the very end, but the only explanation for the final crazy coup de grace is some sort of arbitrary rule. Actually looks like it's 8, 9, or 10 of http://es5.github.com/#x11.9.3. Kind of cool to see that no matter how much precision we come up with, we still have a fallback of "unspecified, return false."
I figured you did, it just makes for a nice narrative :)
isNaN converts non-number (typeof sense) arguments to number, null converts to +0. Relational operators convert too. == looks good by comparison here!
Fixes:
- === and !== of course, since ES1. I tried to make == and != be those in that standard (did so in opt-in JavaScript1.2 in Netscape 4 pre-release), but "don't break the web" came to the fore even back then ('96-'97), from Microsoft (minority share browsers don't like losing share through standards-based incompatibility).
- http://wiki.ecmascript.org/doku.php?id=harmony:number.isnan provides a sane (no argument conversion) isNaN.
- The relational operators try to partially order as many values in JS as possible. While making null convert to NaN to be unordered does seem better in hindsight, the ToNumber(null) => +0 spec is hard to change at this point. Probably the best hope here is an operators proposal that allows customizing operators for any type, not just for "value proxies". This is a dark horse in the Ecma race, but we're working on it in the background.
/be
The main tip with using non-strict equality is ToNumber
conversion. When it's not obvious which result will have the comparison, just start to apply ToNumber
to operands, until you rich the same types, i.e. numbers. Another case -- to use strict ===
equality ;)
P.S.: http://dmitrysoshnikov.com/notes/note-2-ecmascript-equality-operators/
@BrendanEich as always, the history is fascinating - thanks!
this also bothers me:
js> isNaN(null)
false
js> parseFloat(null)
NaN
it makes sense if you read what parseFloat
is supposed to do but still very weird...
@millermedeiros I was confused the same way with parseInt, but I guess it made a little more sense to me that explicit conversions might behave different from implicit coercions. That's why the double-equal thing seemed particularly weird. @BrendanEich Thanks for chiming in with some context and history on this. :)
when null is coerced, it becomes 0, therefore greater than -1 and less than 1, and not greater than 0, nor less than zero... as for that last batshit nonsense, this explains it: http://es5.github.com/#x11.8.5
Have fun with that! :D