javascript - Prevent isNaN implicit conversion to number - Stack Overflow

admin2025-04-09  0

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?

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?

Share Improve this question asked Apr 15, 2015 at 19:13 PhrancisPhrancis 2,2802 gold badges28 silver badges41 bronze badges 1
  • 2 Some browsers support Number.isNaN(), which does not perform the type conversion. – Pointy Commented Apr 15, 2015 at 19:25
Add a ment  | 

4 Answers 4

Reset to default 7

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 plain 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.

isNaN() is not checking if something is not a number type, its literally checking if something is the value "NaN", as you've found. typeof is your friend here.

((typeof foo) === 'number') && !isNaN(foo) should work for what you want.

The purpose of the isNaN function is to check if a value is exactly equal to the built-in NaN constant value. It shouldn't be used to check if something is a number or not, even if that might seem counter-intuitive. It only exists because NaN === NaN returns false, so it's the only way to check if a function involving numbers failed.

Try this:

if (typeof food == "number") {
    console.log("I can't eat " + food + " because it's a number");
} else {
    console.log("I want to eat " + food);
}
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1744202552a235868.html

最新回复(0)