null – 15 = -15? Apparently, yes.

So I discovered that null isn't not a number. Interestingly, it's also not of type "number" (its type is "object"). But it sure acts like a number when used in numerical expressions, which is why it's not not a number, even though it's not actually a number. Honestly. I'm not just writing gibberish here. See for yourself:

alert(typeof null);                     // object
alert(typeof null === 'number');        // false
alert(isNaN(null));                     // false

var x = null - 15;
alert(x);                               // -15

It appears then, that null is interpreted as zero when used in mathematical expressions, which I guess isn't totally illogical (but certainly not what I expected).

var y = null + 25 * 4;
alert(y);                               // 100

A tad more digging and I found (not surprisingly) that this phenomenon is not limited to null. Turns out that many (but not all) "false-like" values are interpreted as zero in mathematical expressions (NaN and undefined being the two exceptions that I noticed):

alert(null * 50);                       // 0
alert("" + 25 * 4);                     // 100
alert(false - 10 * 2);                  // -20
alert(undefined - 100);                 // NaN
alert(NaN + 25);                        // NaN

It's also good to be aware that NaN is "toxic", meaning that the result of a mathematical expression will gravitate towards NaN if it shows up anywhere in the expression, directly (as in the last example above) or indirectly (as in the last two examples shown below):

alert(null + 50);                       // 50, no problem
alert(50 - 'steve');                    // NaN
alert(null + 50 - 'steve');             // NaN

What it means for you

Nothing earth-shattering really -- just that you should be careful if you're using isNaN(..) to find out if something is numeric or not. One thing you can do that (I think) is fool proof is first call parseInt(..) on the value in question and then call isNaN(..) as in:

alert(isNaN(parseInt(null));            // true

This works because parseInt(..) of null is NaN, which of course, will return true when using with isNaN(..).

That's it. Nothing ground-breaking; just something good to keep in the back of your mind so that you spend a few less minutes scratching your head next time your run into it.

Comment welcome.

Got something to say?

Please note: Constructive criticism is welcome. Rude or vulgar comments however, are not and will be removed during moderation.