你如何在 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,它不等于任何东西,甚至它本身”吗?据我所知,NaN
是 javascript 中唯一具有此属性的值。因此你可以写:
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( "" ) = false
和isNaN( ) = true
而Number.isNaN( "" ) = false
和Number.isNaN( ) = false
Polyfill 也可以像Number['isNaN'] || (Number.isNaN = function(a) return a !== a );
一样简单 基本相同,减去几个字符,并将变量集移到运算符的另一侧。
在此处阅读有关 isNaN() 的更多信息:w3schools.com/jsref/jsref_isnan.asp以上是关于你如何在 JavaScript 中测试 NaN?的主要内容,如果未能解决你的问题,请参考以下文章