如何在JavaScript中检查一个数字是NaN ?

我只在Firefox的JavaScript控制台中尝试过,但以下语句都没有返回true:

parseFloat('geoff') == NaN;


parseFloat('geoff') == Number.NaN;
518462 次浏览

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

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

例子:

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

我希望这对你有所帮助。

试试下面的代码:

isNaN(parseFloat("geoff"))

要检查任何值是否为NaN,而不是仅仅是数字,请参见这里:如何在Javascript中测试NaN ?

使用以下代码:

isNaN('geoff');

看到MDN上的isNaN()文档

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

我使用下划线的isNaN函数,因为在JavaScript中:

isNaN(undefined)
-> true

至少,要意识到这一点。

NaN是一个特殊的值,不能这样测试。我想和大家分享一个有趣的事情

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

这为NaN值返回真只有,是一种安全的测试方式。肯定应该被包装在一个函数中,或者至少被注释,因为测试相同的变量是否彼此不相等显然没有多大意义,呵呵。

似乎isNaN()在Node.js的开箱即用中不被支持 我使用了

var value = 1;
if (parseFloat(stringValue)+"" !== "NaN") value = parseFloat(stringValue);

我刚刚在有效的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

虽然@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.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()的false值(true为实布尔值)返回为0!那样的话……相反,parseFloat每次都有效。所以回到这个问题:

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

这似乎涵盖了一切。我将它的基准测试比lodash的_.isNaN慢90%,但这并不能覆盖所有的NaN:

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

只是为了澄清,我的关心人类字面解释的东西是“不是一个数字”和lodash的关心计算机字面解释的检查,如果什么是“NaN”。

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

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

这背后的逻辑是,除了0NaN之外的所有数字都转换为true

我已经做了一个快速测试,它的性能与Number.isNaN一样好,并且可以检查自身是否为false。这三个都比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函数,可能会很有用。

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

NaN === NaN;        // false
Number.NaN === NaN; // false
isNaN(NaN);         // true
isNaN(Number.NaN);  // true

相等运算符(==和===)不能用于测试NaN的值。

看看Mozilla文档全局NaN属性是一个表示Not-A-Numbe的值

最好的方法是使用'isNaN()',这是一个内置函数来检查NaN。所有浏览器都支持这种方式。

简单的解决方案!

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

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

使用简单如下:

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

参见性能测试here使用此func vs < kbd >选择答案< / kbd >

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


例子:

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的聚酯填充 . 0

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

备选方案test if empty

我写了一个简单的窗口方法来测试object是否为空< em > < / em >。它有点不同,因为它没有给出item是否为“完全”南,但我想我会抛出这个,因为它在寻找空项时也可能有用。

/** 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);
})();

例子:

;(function() {
function isEmpty(a) { return !a || void 0 === a || a !== a || 0 >= a || "object" == typeof a && /\{\}|\[(null(,)*)*\]/.test(JSON.stringify(a)); };
window.hasOwnProperty("empty")||(window.empty=isEmpty);
})();


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': new Array(),
'an empty Array w/ 9 len': new Array(9),
'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 = empty(example[x]),
strAnswer = answer.toString();
$("#t1").append(
$("<tr />", { "class": strAnswer }).append(
$("<th />", { html: x }),
$("<td />", { html: strAnswer.toUpperCase() })
)
)
};




function isReallyNaN(a) { return a !== a; };
for(x in example){var answer=isReallyNaN(example[x]),strAnswer=answer.toString();$("#t2").append($("<tr />",{"class":strAnswer}).append($("<th />",{html:x}),$("<td />",{html:strAnswer.toUpperCase()})))};
table { border-collapse: collapse; float: left; }
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 id="t1"><thead><tr><th colspan="2">isEmpty()</th></tr></thead><thead><tr><th>Value Type</th><th>Bool Return</th></tr></thead></table>
<table id="t2"><thead><tr><th colspan="2">isReallyNaN()</th></tr></thead><thead><tr><th>Value Type</th><th>Bool Return</th></tr></thead></table>


极深检查是否为空

最后一个有点深,甚至检查一个对象是否充满了空白对象。我相信它有改进的空间,也有可能出现漏洞,但到目前为止,它似乎能捕捉到几乎所有的东西。

function isEmpty(a) {
if (!a || 0 >= a) return !0;
if ("object" == typeof a) {
var b = JSON.stringify(a).replace(/"[^"]*":(0|"0*"|false|null|\{\}|\[(null(,)?)*\]),?/g, '').replace(/"[^"]*":\{\},?/g, '');
if ( /^$|\{\}|\[\]/.test(b) ) return !0;
else if (a instanceof Array)  {
b = b.replace(/(0|"0*"|false|null|\{\}|\[(null(,)?)*\]),?/g, '');
if ( /^$|\{\}|\[\]/.test(b) ) return !0;
}
}
return false;
}
window.hasOwnProperty("empty")||(window.empty=isEmpty);


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': new Array(),
'an empty Array w/ 9 len': new Array(9),
'a semi-passed parse': parseInt('5a5'),
'a non-empty Array': [ 'a', 'b', 'c' ],
'Math to NaN': Math.log(-1),
'an undefined object': undefined,
'Object Full of Empty Items': { 1: '', 2: [], 3: {}, 4: false, 5:new Array(3), 6: NaN, 7: null, 8: void 0, 9: 0, 10: '0', 11: { 6: NaN, 7: null, 8: void 0 } },
'Array Full of Empty Items': ["",[],{},false,[null,null,null],null,null,null,0,"0",{"6":null,"7":null}]
}


for (x in example) {
var answer = empty(example[x]),
strAnswer = answer.toString();
$("#t1").append(
$("<tr />", { "class": strAnswer }).append(
$("<th />", { html: x }),
$("<td />", { html: strAnswer.toUpperCase() })
)
)
};




function isReallyNaN(a) { return a !== a; };
for(x in example){var answer=isReallyNaN(example[x]),strAnswer=answer.toString();$("#t2").append($("<tr />",{"class":strAnswer}).append($("<th />",{html:x}),$("<td />",{html:strAnswer.toUpperCase()})))};
table { border-collapse: collapse; float: left; }
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 id="t1"><thead><tr><th colspan="2">isEmpty()</th></tr></thead><thead><tr><th>Value Type</th><th>Bool Return</th></tr></thead></table>
<table id="t2"><thead><tr><th colspan="2">isReallyNaN()</th></tr></thead><thead><tr><th>Value Type</th><th>Bool Return</th></tr></thead></table>

如果您的环境支持ECMAScript 2015,那么你可能想要使用Number.isNaN来确保该值确实是NaN

isNaN的问题是,例如,

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

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

Number.isNaN(parseFloat('geoff'))

只要要测试类型为数量的值是否为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两者,我们也可以使用这个填充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;
}

更多细节请查看这个答案

我在StackOverflow上写了这个答案,其中另一个检查时NaN == null,但随后它被标记为重复,所以我不想浪费我的工作。

查看关于NaNMozilla开发者网络


简短的回答

当你想确保你的值是一个正确的数字时,使用distance || 0isNaN()来检查它。

长回答

NaN (Not-a-Number)是javascript中一个奇怪的全局对象,当某些数学操作失败时,经常返回。

你想检查NaN == null是否导致false。然而,即使是NaN == NaN也会导致false

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

另一个是x !== x,仅当x为NaN时为真。(感谢提醒@raphael-schweikert)

但为什么这个简短的答案管用呢?

让我们一探究竟。

当你调用NaN == false时,结果是false,与NaN == true相同。

在规范中,JavaScript有一个总是false值的记录,包括:

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

ES6开始,Object.is(..)是一个新的实用程序,可用于测试两个值是否绝对相等:

var a = 3 / 'bar';
Object.is(a, NaN); // true

另一个解决方案在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

准确的检查方法是:

//takes care of boolen, undefined and empty


isNaN(x) || typeof(x) ==='boolean' || typeof(x) !=='undefined' || x!=='' ? 'is really a nan' : 'is a number'
我已经创建了这个小函数,它的工作就像一个魅力。 而不是检查NaN,这似乎是违反直觉的,你检查一个数字。我很确定我不是第一个这样做的人,但我想我要分享
function isNum(val){
var absVal = Math.abs(val);
var retval = false;
if((absVal-absVal) == 0){
retval = true
}


return retval;
}

简单地将结果转换为String并与'NaN'进行比较。

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

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

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

marksyzm的答案工作得很好,但它不会为Infinity返回false,因为Infinity在技术上不是一个数字。

我想出了一个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"));

< p >更新: 我注意到这段代码在某些参数上失败了,所以我让它更好

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));

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

这并不优雅。但在尝试isNAN()后,我得到了这个解决方案,这是另一种选择。在这个例子中,我还允许'。'因为我正在为浮动进行屏蔽。您还可以反转此操作,以确保不使用任何数字。

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

这是一个单个字符的求值,但您也可以循环遍历字符串以检查任何数字。

function isNotANumber(n) {
if (typeof n !== 'number') {
return true;
}
return n !== n;
}

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

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

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

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

条件仅在真正的. if执行。

而不是

不是在"我不知道"上。

对此我看到了一些回应,

但我只用:

function isNaN(x){
return x == x && typeof x == 'number';
}

也许还有这个:

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

规则是:

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"))
Number('hello').toString() === 'NaN' // true
Number(undefined).toString() === 'NaN' // true
    

Number('12345').toString() === 'NaN' // false


// These all evaluate to 0 which is a number
Number('').toString() === 'NaN' // false // 0
Number('0').toString() === 'NaN' // false // 0
Number().toString() === 'NaN' // false // 0


// These all evaluate to 0 and 1 which is a number
Number(false).toString() === 'NaN' // false // 0
Number(true).toString() === 'NaN' // false // 1

两种都试试看

if(isNaN(parseFloat('geoff'))  && typeof(parseFloat('geoff')) === "number");
//true

发现这很有用

    // Long-hand const isFalsey = (value) => {   if (
value === null ||
value === undefined ||
value === 0 ||
value === false ||
value === NaN ||
value === ""   ) {
return true;   }   return false; };
// Short-hand const
isFalsey = (value) => !value;