28 January 2015

isNaN VS Math.isNaN

I have been writing underscore.coffee and in doing so I decided to recreate isNaN.

  _.isNaN = (value) ->
Number.isNaN(value)
  

There is a method on the global object called isNaN. There is also a method on the Number object called isNaN. Do you know the difference? The global isNaN returns true if passed the value undefined, which is clearly incorrect. Number.isNaN returns false for undefined values and returns true only for NaN values.

NaN is a Number

I originally thought 'not a number' meant a mathematical expression evaluated to a value that was a type other than Number. I later realized that 'not a number' really means 'not a real number'. NaN is actually meant to represent mathematical expressions which result in values that cannot be expressed in the number set JavaScript provides. For example, imaginary numbers cannot be represented in JavaScript. If an expression is performed that creates an imaginary number then JavaScript will raise NaN. Imaginary numbers are numbers though, they are just numbers that cannot be represented in JavaScript. Therefore, 'not a number' should more accurately be called 'not a real number'. JavaScript can only represent real numbers and everything else is considered NaN. This is why the data type of NaN is number.

  typeof NaN
  >>>"number"
  

So there you have it, not a number is a number!