关于javascript:是什么导致isNaN出现故障?

What causes isNaN to malfunction?

本问题已经有最佳答案,请猛点这里访问。

我只是想评估一个输入是否是一个数字,计算出isNaN是最好的方法。然而,这会导致不可靠的结果。例如,使用以下方法:

1
2
3
4
function isNumerical(value) {
    var isNum = !isNaN(value);
    return isNum ?"<mark>numerical</mark>" :"not numerical";
}

关于这些值:

1
2
3
4
5
6
isNumerical(123));     // => numerical
isNumerical("123"));   // => numerical
isNumerical(null));    // => numerical
isNumerical(false));   // => numerical
isNumerical(true));    // => numerical
isNumerical());        // => not numerical

如图所示:http://jsfiddle.net/4nm7r/1

为什么isNaN不总是为我工作?


如果传递的值不是数字(NaN)(或不能转换为数字,那么,isNaN返回true,因此,nulltruefalse将转换为0,否则返回false。在您的情况下,您必须在函数调用之前删除!

很容易理解脚本的行为。isNaN简单地检查一个值是否可以转换成一个int。要做到这一点,您只需将它乘以或除以1,或减去或加上0。在您的例子中,如果您这样做,那么在函数内部,alert(value * 1);将看到所有传递的值都将被一个数字(0、1、123)替换,但undefined除外,它的数值为NaN

您不能将任何值与NaN进行比较,因为它永远不会返回false(即使是NaN === NaN),我认为这是因为nan是动态生成的…但我不确定。

无论如何,您可以通过执行以下操作来修复代码:

1
2
3
4
function isNumerical(value) {
    var isNum = !isNaN(value / 1); //this will force the conversion to NaN or a number
    return isNum ?"<mark>numerical</mark>" :"not numerical";
}


我建议您使用其他支票:

1
2
3
4
function isNumerical(value) {
    var isNum = !isNaN(value) && value !== null && value !== undefined;
    return isNum ?"<mark>numerical</mark>" :"not numerical";
}

如果您希望将像123这样的字符串视为非数字字符串,则应再添加一个检查:

1
var isNum = !isNaN(value) && value !== null && value !== undefined && (typeof value === 'number');


既然你已经修正了其他答案所指出的逆向逻辑,那么就用parseFloat来消除truefalsenull的误报:

1
var isNum = !isNaN(parseFloat(value));

请记住,parseFloat的以下输出类型:

1
2
3
4
parseFloat("200$"); // 200
parseFloat("200,100"); // 200
parseFloat("200 foo"); // 200
parseFloat("$200"); // NaN

(即,如果字符串以数字开头,ParseFloat将提取它能找到的第一个数字部分)


你的三元语句是向后的,如果!isNaN()返回真值,你想说"numerical"

1
return isNum ?"not numerical" :"<mark>numerical</mark>";

应该是:

1
return isNum ?"<mark>numerical</mark>" :"not numerical";

参见更新的小提琴:

http://jsfiddle.net/4nm7r/1/