如何检查JavaScript中的数字是否为NaN?


414

我只是在Firefox的JavaScript控制台中尝试过,但是以下任何一条都不返回true:

parseFloat('geoff') == NaN;

parseFloat('geoff') == Number.NaN;

5
如果您的实际目标是检查数字,则值得一读: stackoverflow.com/questions/18082/…–
Paul


1
@Gothdo:可以,但是我确实问过如何检查数字是否为NaN而不是任何值。
Paul D. Waite

2
@ PaulD.Waite是的,但是在谷歌搜索诸如“如何检查javascript中变量是否为nan”之类的内容时,会有很多人来这里。
米哈尔Perłakowski

PaulD.Waite我同意你的看法,但我和@Gothdo一样担心。许多人以“如何检查JS中的值是否为NaN”的意图着手解决此问题。您可以检查mjohnsonengr对相同答案的评论。顺便说一句,我也已将此问题标记为主持人注意。
dopeddude

Answers:


581

试试这个代码:

isNaN(parseFloat("geoff"))

要检查是否数值而不是数字而不是数字NaN,请参见此处:如何在Javascript中测试NaN?


8
是否需要paseFloat?
rahul

23
如果您希望将空字符串解释为NaN,则可以。(我并不是说你总是会的。)
保罗·D·威特

1
如果我是我,我会将其分配给变量,然后使用条件变量!== variable。如规格书tc39.github.io/ecma262/#sec-isnan-number中所述
变态

3
isNaN(parseFloat("geoff")) // true isNaN(parseFloat("10geo")) // false 这有什么用?
Prashanth


146

我刚刚在《有效JavaScript》一书中遇到了这种技术,它很简单:

由于NaN是唯一被视为与自身不相等的JavaScript值,因此您始终可以通过检查其与自身的相等性来测试该值是否为NaN:

var a = NaN;
a !== a; // true 

var b = "foo";
b !== b; // false 

var c = undefined; 
c !== c; // false

var d = {};
d !== d; // false

var e = { valueOf: "foo" }; 
e !== e; // false

直到@allsyed发表评论才意识到这一点,但这在ECMA规范中:https ://tc39.github.io/ecma262/#sec-isnan-number


27
有效,但违反直觉。我不想维护这种代码。
osa 2014年

35
违反直觉的不是代码,而是NaN。
爵士乐

20
@DanM不是错误,这是NaN的标准IEE754行为。它是在CPU中实现的方式,也是世界上所有使用浮点数的编程语言中的预期行为。
塔米尔2014年

4
@Tarmil Duly指出了!这真的很有趣;我一直以为NaN不等式怪异是Java语言。
Dan M

2
NaN === Nan; //错误。这是javascript中的已知错误。isNan是一种新方法。
atilkan

52

使用此代码:

isNaN('geoff');

请参阅isNaN()MDN上的文档

alert ( isNaN('abcd'));  // alerts true
alert ( isNaN('2.0'));  // alerts false
alert ( isNaN(2.0));  // alerts false

1
也许这只是我,但楠想法被混淆的时候var value = 0/0;,并var value2= String("123 131");创建NaN值和这样的事情var value3 = "abcd";也是NaN值。
尼克·皮内达

@NickPineda为什么?
Sinjai

44

至于是否要测试Number类型的值NaN,则全局函数isNaN将完成工作

isNaN(any-Number);

对于适用于JS中所有类型的通用方法,我们可以使用以下任何一种方法:

对于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用于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;
}

请检查此答案以获取更多详细信息。


6
感谢您不仅使用“ isNan()”,而且还提供了完整的详细答案。这正是我在Google上发现此问题时要寻找的东西。
mjohnsonengr 2015年

1
“……在上述情况下给出了错误的结果”我不会说错,只是不同,因为全局isNaN变量首先将参数转换为数字值。
菲利克斯·克林

1
@FelixKling请检查更新的答案。谢谢。
dopeddude

1
isNaN(“ lorem ipsum”); //与ES5真正吹我的脑海里
尼克·皮内达

2
@NickPineda这种感觉是如此共同,但是最终MDN可以这样解释:“当isNaN函数的参数不是Number类型时,该值首先被强制为Number。然后测试结果值以确定它是否为Number NaN。”
dopeddude

16

NaN是一个特殊的值,无法像这样进行测试。我只想分享的一件有趣的事是

var nanValue = NaN;
if(nanValue !== nanValue) // Returns true!
    alert('nanValue is NaN');

仅对 NaN值返回true ,这是一种安全的测试方法。绝对应该将其包装在函数中或至少注释一下,因为测试同一个变量是否彼此不相等显然没有多大意义,呵呵。


1
那不是一个完全可靠的方法。根据规格。变数==变数是检查NaN的最可靠方法
2014年

1
^^
Jazzy's

14

您应该使用全局isNaN(value)函数调用,因为:

  • 支持跨浏览器
  • 有关文档,请参见isNaN

例子:

 isNaN('geoff'); // true
 isNaN('3'); // false

我希望这能帮到您。


1
是的,isNaN('') //false但是parseInt('') //NaN。可以这样说null
沉默企鹅


9

要解决'1.2geoff'被解析的问题,只需使用Number()解析器即可。

所以而不是这样:

parseFloat('1.2geoff'); // => 1.2
isNaN(parseFloat('1.2geoff')); // => false
isNaN(parseFloat('.2geoff')); // => false
isNaN(parseFloat('geoff')); // => true

做这个:

Number('1.2geoff'); // => NaN
isNaN(Number('1.2geoff')); // => true
isNaN(Number('.2geoff')); // => true
isNaN(Number('geoff')); // => true

编辑:我只是从中注意到了另一个问题……假值(和真实的布尔值)传递给Number()return as 0!在这种情况下,parseFloat每次都起作用。所以回到那个:

function definitelyNaN (val) {
    return isNaN(val && val !== true ? Number(val) : parseFloat(val));
}

这似乎涵盖了所有内容。我将其基准测试的速度比lodash的速度慢90%,_.isNaN但随后并没有涵盖所有的NaN:

http://jsperf.com/own-isnan-vs-underscore-lodash-isnan

只是要清楚一点,我的是对“不是数字”的东西进行人类文字解释,而洛达德则是检查东西是否为“ NaN”的计算机文字解释。


7

尽管@chiborg的答案是正确的,但还有更多需要注意的地方:

parseFloat('1.2geoff'); // => 1.2
isNaN(parseFloat('1.2geoff')); // => false
isNaN(parseFloat('.2geoff')); // => false
isNaN(parseFloat('geoff')); // => true

重要的是,如果您使用这种方法来验证输入,结果将是相当自由的。

因此,是的,您可以使用parseFloat(string)(或在全数字的情况下使用parseInt(string, radix)',然后用来将其包裹起来isNaN(),但要注意,数字与其他非数字字符交织在一起的陷阱。


1
有趣。有什么办法可以解决这个问题并检测到“ 1.2geoff”实际上不是有效的数字字符串吗?
·霍尔斯默

2
请注意,仅当字符串数字开头时,才会发生这种情况。parseFloat('test1.2')会回来的NaN
爱德华·卢卡

6

简单的解决方案!

真的超级简单!这里!有这个方法!

function isReallyNaN(a) { return a !== a; };

使用方法如下:

if (!isReallyNaN(value)) { return doingStuff; }

here使用此功能对比性能测试selected answer

另外:请参见下面的第一个示例,了解几个替代实现。


例:

function isReallyNaN(a) { return a !== a; };

var example = {
    'NaN': NaN,
    'an empty Objet': {},
    'a parse to NaN': parseFloat('$5.32'),
    'a non-empty Objet': { a: 1, b: 2 },
    'an empty Array': [],
    'a semi-passed parse': parseInt('5a5'),
    'a non-empty Array': [ 'a', 'b', 'c' ],
    'Math to NaN': Math.log(-1),
    'an undefined object': undefined
  }

for (x in example) {
    var answer = isReallyNaN(example[x]),
        strAnswer = answer.toString();
    $("table").append($("<tr />", { "class": strAnswer }).append($("<th />", {
        html: x
    }), $("<td />", {
        html: strAnswer
    })))
};
table { border-collapse: collapse; }
th, td { border: 1px solid; padding: 2px 5px; }
.true { color: red; }
.false { color: green; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table></table>

如果您不想使用替代命名的方法,并且想确保该方法在全球范围内可用,则有几种实现方法。警告这些解决方案涉及更改本机对象,可能不是最佳解决方案。请务必谨慎,并注意您可能使用的其他库可能取决于本机代码或类似的更改。

替代实现1:替换本机isNaN方法。

//  Extremely simple. Just simply write the method.
window.isNaN = function(a) { return a !==a; }

替代实现2:附加到数字对象
*建议使用,因为它也是ECMA 5至6的填充

Number['isNaN'] || (Number.isNaN = function(a) { return a !== a });
//  Use as simple as
Number.isNaN(NaN)

备用溶液测试是否为空

我编写了一个简单的窗口方法来测试object是否为Empty。有点不同,因为项目“是” NaN不会给出,但我认为我会把它扔掉,因为它在寻找空项目时也很有用。

/** isEmpty(varried)
 *  Simple method for testing if item is "empty"
 **/
;(function() {
   function isEmpty(a) { return (!a || 0 >= a) || ("object" == typeof a && /\{\}|\[(null(,)*)*\]/.test(JSON.stringify(a))); };
   window.hasOwnProperty("empty")||(window.empty=isEmpty);
})();

例:


极深检查是否为空

最后一个要深入一点,甚至检查对象是否充满空白对象。我敢肯定它还有改进的余地和可能的缺陷,但是到目前为止,它似乎涵盖了大多数内容。


1
@ PaulD.Waite也许是这个应用程序,但是我没有看到一个被接受的答案。实际上,我只看到大约5个答案,但我看到它说有15个答案
SpYk3HH 2015年

1
您正在使用什么应用程序?
Paul D. Waite,2015年

2
@ PaulD.Waite SE安卓版。在银河s3上
SpYk3HH 2015年

1
啊哈 我没有让我自己看的应用程序,但以下是已接受答案的链接:stackoverflow.com/a/2652335/20578
Paul D. Waite 2015年

@ PaulD.Waite啊,我明白了。我想,仅对问题本身进行直接回答,这个回答就足够了。我将我的答案发布在另一个问题上,该问题与“检查JS是否真的是NaN的JS方式”完全相关,因为isNaN它不可靠。我在那里被评论,并告诉这个问题更适合我的答案,因此将其移到此处。只需在此问题上提出一些有用/有用的信息,就会在Google对当前问题的搜索中弹出is it NaN?。附带一提,我的答案会比选定答案更准确。
SpYk3HH 2015年

5

我只想分享另一种选择,它不一定比这里的其他更好,但是我认为值得研究:

function customIsNaN(x) { return (typeof x == 'number' && x != 0 && !x); }

其背后的逻辑是,除0和外的每个数字NaN都强制转换为true

我已经进行了快速测试,它的性能Number.isNaN与检查自身是否为假一样好。这三个都比isNan

结果

customIsNaN(NaN);            // true
customIsNaN(0/0);            // true
customIsNaN(+new Date('?')); // true

customIsNaN(0);          // false
customIsNaN(false);      // false
customIsNaN(null);       // false
customIsNaN(undefined);  // false
customIsNaN({});         // false
customIsNaN('');         // false

如果要避免isNaN功能中断,可能会很有用。


5

如果您的环境支持ECMAScript 2015,则可能需要使用Number.isNaN确保该值确实为NaN

问题isNaN是,如果您将其与非数字数据一起使用,则几乎没有适用的混淆规则(按照MDN)。例如,

isNaN(NaN);       // true
isNaN(undefined); // true
isNaN({});        // true

因此,在ECMA Script 2015支持的环境中,您可能需要使用

Number.isNaN(parseFloat('geoff'))

7
我的环境仅支持ECMAScript XP Home Edition :(
Paul D. Waite,2015年

1
@ PaulD.Waite(我希望您的意思是IE 6:D)没问题:-)请记住,这isNaN可能Number.isNaN
会给

5

JavaScript中的NaN代表“不是数字”,尽管其类型实际上是数字。

typeof(NaN) // "number"

要检查变量的值是否为NaN,我们不能简单地使用函数isNaN(),因为isNaN()存在以下问题,请参见下文:

var myVar = "A";
isNaN(myVar) // true, although "A" is not really of value NaN

真正发生的是myVar被隐式强制为数字:

var myVar = "A";
isNaN(Number(myVar)) // true. Number(myVar) is NaN here in fact

这实际上是有道理的,因为“ A”实际上不是数字。但是,我们真正要检查的是myVar是否完全值NaN。

因此isNaN()无济于事。那我们该怎么办呢?

考虑到NaN是唯一一个与自身不相等的JavaScript值,因此我们可以使用!==检查其与自己的相等性。

var myVar; // undefined
myVar !== myVar // false

var myVar = "A";
myVar !== myVar // false

var myVar = NaN
myVar !== myVar // true

因此,可以得出结论,如果确实是一个变量!==本身,则该变量的值恰好为NaN:

function isOfValueNaN(v) {
    return v !== v;
}

var myVar = "A";
isNaN(myVar); // true
isOfValueNaN(myVar); // false

4

我使用下划线isNaN功能,因为在JavaScript中:

isNaN(undefined) 
-> true

至少要注意该陷阱。


10
我糊涂了。为什么NaN传递时返回true undefined是不正确的行为?确实undefined不是数字,不是吗?
Xaxis

3
@Xaxis NaN不应被视为等同于undefined,它们都是具有特定含义和不同含义的特殊值。考虑一下:我有一个值,但我没有告诉它是什么,也许这是一个数字,但是从您的角度来看,它不是一个未定义的值。
科林2014年

1
@Corin undefined可能与有所不同NaN,但是仍然不是一个数字,isNaN(undefined)应该(而且是)true
neuhaus

4

也许也是这样:

function isNaNCustom(value){
    return value.toString() === 'NaN' && 
           typeof value !== 'string' && 
           typeof value === 'number'
}




2

规则是:

NaN != NaN

isNaN()函数的问题是在某些情况下它可能返回意外结果:

isNaN('Hello')      //true
isNaN('2005/12/12') //true
isNaN(undefined)    //true
isNaN('NaN')        //true
isNaN(NaN)          //true
isNaN(0 / 0)        //true

检查该值是否真的为NaN的更好方法是:

function is_nan(value) {
    return value != value
}

is_nan(parseFloat("geoff"))

1

根据IEEE 754,除!=之外,所有涉及NaN的关系都评估为false。因此,例如,如果A或B或两者均为NaN,则(A> = B)=假,(A <= B)=假。


1

我将此答案写在StackOverflow上的另一个问题上,其中另一个检查何时进行,NaN == null但是后来被标记为重复,所以我不想浪费我的工作。

查看有关Mozilla开发者网络的信息NaN


简短答案

只要使用distance || 0的时候你要确保你值是适当的数量或isNaN()要检查它。

长答案

NaN(非数字)是JavaScript中的一个怪异全局对象,在某些数学运算失败时经常返回。

您想检查是否NaN == null有结果false。甚至可以NaN == NaN得到结果false

一种简单的确定变量是否NaN为全局函数的方法isNaN()

另一个是 x !== x只有当x为NaN时才成立。(感谢提醒@ raphael-schweikert)

但是为什么简短的答案行得通呢?

让我们找出答案。

调用NaN == false结果为时false,与相同NaN == true

在规范的某个地方,JavaScript的记录始终为假值,其中包括:

  • NaN -非数字
  • "" -空字符串
  • false -布尔值false
  • null -空对象
  • undefined -未定义的变量
  • 0 -数字0,包括+0和-0

1
“确定变量是否为NaN的唯一简单方法是全局函数isNaN()” –不正确;还有另一种简单的方法:var xIsNaN = x !== x;仅当x为时,才产生true NaN
拉斐尔·施维克

1

MDN的parseFloat页面中提到了另一种解决方案

它提供了过滤功能以进行严格的解析

var filterFloat = function (value) {
    if(/^(\-|\+)?([0-9]+(\.[0-9]+)?|Infinity)$/
      .test(value))
      return Number(value);
  return NaN;
}


console.log(filterFloat('421'));               // 421
console.log(filterFloat('-421'));              // -421
console.log(filterFloat('+421'));              // 421
console.log(filterFloat('Infinity'));          // Infinity
console.log(filterFloat('1.61803398875'));     // 1.61803398875
console.log(filterFloat('421e+0'));            // NaN
console.log(filterFloat('421hop'));            // NaN
console.log(filterFloat('hop1.61803398875'));  // NaN

然后您可以使用isNaN它来检查NaN


1

确切的检查方法是:

//takes care of boolen, undefined and empty

isNaN(x) || typeof(x) ==='boolean' || typeof(x) !=='undefined' || x!=='' ? 'is really a nan' : 'is a number'

1

我创建了这个小功能,就像一个魅力。您可以检查数字,而不是检查似乎反直观的NaN。我很确定我不是第一个这样做的人,但是我想我会分享的。

function isNum(val){
    var absVal = Math.abs(val);
    var retval = false;
    if((absVal-absVal) == 0){
        retval = true
    }

    return retval;
}

1

找到了另一种方式,只是为了好玩。

function IsActuallyNaN(obj) {
  return [obj].includes(NaN);  
}

1

marksyzm的答案效果很好,但Infinity由于Infinity从技术上讲不是数字,因此不会返回false 。

我想出了一个isNumber功能,将检查它是否是一个数字。

function isNumber(i) {
    return !isNaN(i && i !== true ? Number(i) : parseFloat(i)) && [Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY].indexOf(i) === -1;
}

console.log(isNumber(Infinity));
console.log(isNumber("asdf"));
console.log(isNumber(1.4));
console.log(isNumber(NaN));
console.log(isNumber(Number.MAX_VALUE));
console.log(isNumber("1.68"));

更新:我注意到该代码对于某些参数失败,所以我做得更好。

function isNumber(i) {//function for checking if parameter is number
if(!arguments.length) {
throw new SyntaxError("not enough arguments.");
	} else if(arguments.length > 1) {
throw new SyntaxError("too many arguments.");
	} else if([Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY].indexOf(i) !== -1) {
throw new RangeError("number cannot be \xB1infinity.");
	} else if(typeof i === "object" && !(i instanceof RegExp) && !(i instanceof Number) && !(i === null)) {
throw new TypeError("parameter cannot be object/array.");
	} else if(i instanceof RegExp) {
throw new TypeError("parameter cannot be RegExp.");
	} else if(i == null || i === undefined) {
throw new ReferenceError("parameter is null or undefined.");
	} else {
return !isNaN(i && i !== true ? Number(i) : parseFloat(i)) && (i === i);
	}
}
console.log(isNumber(Infinity));
console.log(isNumber(this));
console.log(isNumber(/./ig));
console.log(isNumber(null));


您的前提是技术上无穷大不是技术上有缺陷的:math.stackexchange.com/questions/36289/is-infinity-a-number。根据我对答案的理解,无穷大是数字取决于上下文。
乔恩·P

我将把这个问题移到另一个问题上
adddff '17

1
alert("1234567890.".indexOf(String.fromCharCode(mycharacter))>-1);

这不优雅。但是在尝试isNAN()之后,我得出了这个解决方案,这是另一种选择。在此示例中,我还允许使用“。”。因为我要掩盖浮标。您也可以反向进行此操作以确保不使用任何数字。

("1234567890".indexOf(String.fromCharCode(mycharacter))==-1)

这是一个单字符评估,但您也可以遍历字符串以检查任何数字。


1

您可以使用isNaN javascript函数检查NaN。只是将数字或值传递给isNaN函数

isNaN(123) //false
isNaN(-1.23) //false
isNaN(5-2) //false
isNaN(0) //false
isNaN('123') //false
isNaN('Hello') //true
isNaN('2005/12/12') //true
isNaN('') //false
isNaN(true) //false
isNaN(undefined) //true
isNaN('NaN') //true
isNaN(NaN) //true
isNaN(0 / 0) //true

0

只需将结果转换为String并与'NaN'比较即可。

var val = Number("test");
if(String(val) === 'NaN') {
   console.log("true");
}

0

(NaN> = 0)吗?……“ 我不知道 ”。

function IsNotNumber( i ){
    if( i >= 0 ){ return false; }
    if( i <= 0 ){ return false; }
    return true;
}

条件仅在TRUE时执行。

不开 FALSE

不在“ 我不知道 ”上。


如果您明确寻找NaN值而不是寻找相反的值,则不是很有用
liviu blidar '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.