Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent isNaN implicit conversion to number

I'm learning some JavaScript and ran into a quirk and was wondering if anyone knew a way to override this behavior. I'd like to be able to test if a value passed to a function is a real number, and I thought using === for the isNaN() check would take care of that, but it doesn't.

Example function:

var foodDemand = function(food) {
    if (isNaN(food) === false) {
        console.log("I can't eat " + food + " because it's a number");
    } else {
        console.log("I want to eat " + food);
    }
};

And I test with this:

// behaves as expected
foodDemand("steak");
foodDemand(999999999);
foodDemand(0.0000001337);
foodDemand([1]);
foodDemand(undefined);
foodDemand(NaN);
foodDemand({});
// converts non-number to a number
foodDemand("42");
foodDemand("");
foodDemand(null);
foodDemand([]);
foodDemand("\n");

Output (italics represent unexpected results):

I want to eat steak
I can't eat 999999999 because it's a number
I can't eat 1.337e-7 because it's a number
I can't eat 1 because it's a number
I want to eat undefined
I want to eat NaN
I want to eat [object Object]
I can't eat 42 because it's a number
I can't eat  because it's a number
I can't eat null because it's a number
I can't eat  because it's a number
I can't eat 
 because it's a number

Is there any way to make isNaN() more strict?

like image 416
Phrancis Avatar asked Oct 16 '25 18:10

Phrancis


1 Answers

isNaN's purpose is not really to test if something is litterally not a number, but to test if something is the number NaN (since NaN===NaN returns false in JavaScript you can't use equality).

You should use typeof instead, and then isNaN:

if((typeof food)==="number" && !isNaN(food))

Why, you may ask, is NaN not equal to NaN ?? Is that one more of JavaScript's infamous quirks?

Turns out there is a good reason for this behavior. Mathematical operations that can't return a real result, not even Infinity, will not complain and throw an error. They just return NaN. For example, 0/0, sqrt(-1), acos(2). Wouldn't it be weird to have Math.sqrt(-1) === 0/0? So NaN is not equal to even itself. And therefore, a primitive like isNaN is needed in case you actually want to check if a value is NaN.

like image 136
Touffy Avatar answered Oct 18 '25 09:10

Touffy