NaN? Back

Before talking about something about NaN, we should know that what it means. Actually NaN is also called as Not-A-Number value, which means that the value is not a number. It's usually returned as a result after failed to calculate some expression like Math.sqrt(-1), or parseInt('number'). Of course, you may also have seen Number.NaN, which is completely same as NaN. Furthermore, they're both Number types:

console.log(Object.prototype.toString.call(NaN)); /** => "[object number]" */
console.log(Object.prototype.toString.call(Number.NaN)); /** => "[object number]" */

Although NaN is a Number, it is not equal to itself:

console.log(NaN == NaN); /** => false */
console.log(NaN === NaN); /** => false */

However, the global method isNaN will always return true when judging whether a value is NaN:

isNaN(NaN); /** => true */
isNaN(undefined); /** => true */
isNaN({}); /** => true */
isNaN('number'); /** => true */

That's because the value passed into the method will be firstly converted into Number types:

Number(NaN); /** => NaN */
Number(undefined); /** => NaN */
Number({}); /** => NaN */
Number("abc"); /** => NaN */

Then, ES6 has imported Number.isNaN() to judge strictly:

isNaN = function (value) {
    return Number(value) === NaN;
};

Number.isNaN = Number.isNaN || function (value) {
    return typeof value === 'number' && isNaN(value);
};

However, this implementation still have a problem:

Number.isNaN(new Number(NaN)); /** => false */

Therefore, underscore has fixed by implementing this:

_.isNaN = function (obj) {
    return Object.prototype.toString.call(obj) === '[object Number]' && obj !== +obj;
};

But this causes a huge problem:

_.isNaN(new Number(0)); /** => true */
_.isNaN(new Number(1)); /** => true */

Therefore, the most elegant way to implement this method should be:

_.isNaN = function (obj) {
    return Object.prototype.toString.call(obj) === '[object Number]' && isNaN(obj);
};

results matching ""

    No results matching ""