你如何在 JavaScript 中测试 NaN?

Posted

技术标签:

【中文标题】你如何在 JavaScript 中测试 NaN?【英文标题】:How do you test for NaN in JavaScript? 【发布时间】:2015-07-30 14:54:48 【问题描述】:

我有一个变量 x,我想测试 x 是否设置为 NaN。我该怎么做?

我的第一直觉可能是,你知道,测试它,像这样:

if (x === NaN)   ...

傻兔子,不,那太容易了。 NaN 就像 SQL 中的 NULL,它不等于任何东西,甚至它本身。

但是看,有一个名为isNaN() 的函数——也许可以做到!

不,据我所知,isNaN() 完全没有价值。

例如,isNaN([""]) 正确返回 false,但 isNaN(["."]) 返回 true。你不想知道我是怎么知道这个缺陷的。

我该怎么做?

原来,我的问题与this one 重复,但选择的答案是错误的。 right answer 有 20% 的赞成票。

【问题讨论】:

"你不想知道我是怎么知道这个缺陷的。" - 我想知道你为什么要在数组上调用isNaN @Bergi -- 我正在写一个日期选择器。当["2015", "05", "05"] 被标记为 NaN 时,我差点打到屏幕。 但是你为什么期望一个数组表现得像一个数字呢? @Bergi -- 我不是。 Angular 给我 NaN 的意思是“数据尚不可用”,而实际数据(在这种情况下是一个数组)是可用的。我需要一种方法来知道数据是否存在。 @Bergi -- 如果您查看the original question,您会看到问题:如果数据尚未准备好,Angular 会使用 NaN 调用 ngModel.$render,如果数据准备好则使用数据。数据在一种情况下是一个数组,但还有很多其他情况。当然,没有理由认为 NaN 本身不能成为合法值…… 【参考方案1】:

如果你仔细阅读,这个问题就会有答案。这就是我找到它的方式:我正在输入问题并且......宾果游戏。

你还记得我写的“NaN就像SQL中的NULL,它不等于任何东西,甚至它本身”吗?据我所知,NaNjavascript 中唯一具有此属性的值。因此你可以写:

var reallyIsNaN = function(x) 
   return x !== x;
;

【讨论】:

阅读MDN docs for Number.NaN后,建议同时检查typeof x === "number"isNaN 的不同之处在于它在比较之前将值强制为一个数字(+[] == 0,wat?) @thgaskell 当你说 +[] == 0 时,javascript 会尝试将数组的第一个值转换为整数。尝试将 array[0] 调用为空数组,它将返回未定义。这个转换不等于parseInt,undefined会被转换为0,试试+[1]和+['1223fsds']。最后 0 == 0。这就是你得到这个结果的原因。 @thgaskell 是的,我看过视频。这很有趣。查看此帖子***.com/questions/30325896/… @thgaskell - wat 不是wat。 请保持冷静,记住 Java、C#、Python、Scala、C++(在 clang、g++ 和 msvc 下)都具有与 JavaScript 相同的 NaN 行为。在所有这些语言中,0/0 是 NaN,并且在所有这些语言中,NaN 都不等于它自己。就是what the standard requires【参考方案2】:

简答

对于 ECMAScript-5 用户:

#1
if(x !== x) 
    console.info('x is NaN.');

else 
    console.info('x is NOT a NaN.');

对于使用 ECMAScript-6 的人:

#2
Number.isNaN(x);

为了在 ECMAScript 5 和 6 之间保持一致性,您也可以使用 polyfill for Number.isNan

#3
//Polyfill from MDN
Number.isNaN = Number.isNaN || function(value) 
    return typeof value === "number" && isNaN(value);

// Or
Number.isNaN = Number.isNaN || function(value)      
    return value !== value;

注意:我更喜欢使用 #1 进行测试,它在所有地方都适用,并且也不依赖于最新的 JS。 (它总是给我正确的结果。没有惊喜!)


详细说明:

这是我们很棒的 NaN

NaN == NaN; // false
NaN === NaN; // false

请不要为此责备JavaScript,NaN 在其他语言中也应该以这种方式表现,根据rationale for all comparisons returning false NaN values,这很好

isNaN 作为我们的救星出现了,但在某些情况下,它的行为略有不同,例如

isNaN(undefined); // true
isNaN();        // true
isNaN("lorem ipsum"); // true

看到上面的结果,我有一些奇怪的面孔。这就是来自 MDN 的原因

当 isNaN 函数的参数不是 Number 类型时,首先将值强制转换为 Number。然后测试结果值以确定它是否为 NaN。

那么我们应该如何测试非数字变量的 NaN 呢?我总是按照以下方式进行

if(x !== x) 
    console.info('Is a NaN');

else 
    console.info('Not a NaN');

ECMAScript-6/JavaScript-2015 更新

我们在 ECMAScript-6 中有什么相同的吗?是的,我们确实...

Number.isNaN(x); // true

ES6 实现也会对上述情况有所帮助,例如

Number.isNaN(undefined); // false
Number.isNaN(); // false    
Number.isNaN("lorem ipsum"); // false

而对于上述情况,ECMAScript-5 全局函数 isNaN 输出为 true,这有时可能与我们的预期不一致。

【讨论】:

喜欢isNaN( "" ) = falseisNaN( ) = trueNumber.isNaN( "" ) = falseNumber.isNaN( ) = false Polyfill 也可以像Number['isNaN'] || (Number.isNaN = function(a) return a !== a ); 一样简单 基本相同,减去几个字符,并将变量集移到运算符的另一侧。 在此处阅读有关 isNaN() 的更多信息:w3schools.com/jsref/jsref_isnan.asp

以上是关于你如何在 JavaScript 中测试 NaN?的主要内容,如果未能解决你的问题,请参考以下文章

你如何对 JavaScript 代码进行性能测试?

如何检测指定数量是不是为 NaN 以及如何[重复]

如何检查单元测试中的值是不是为nan?

JavaScript的NaN-唯一 一个自己不等于自己的对象!!

打字稿:仅测试 Nan、null 和 undefined

如何检查NaN javascript的相等性[重复]