How do you check that a number is NaN in JavaScript?
我只是在Firefox的JavaScript控制台中尝试过,但以下两个语句都没有返回true:
1 2 3 | parseFloat('geoff') == NaN; parseFloat('geoff') == Number.NaN; |
试试这段代码:
1 | isNaN(parseFloat("geoff")) |
要检查是否有任何值是NaN,而不仅仅是数字,请参阅此处:如何在Javascript中测试NaN?
我刚刚在"有效JavaScript"一书中遇到过这种技巧,非常简单:
由于NaN是唯一被视为与其自身不相等的JavaScript值,因此您可以通过检查值是否为NaN来测试它是否与自身相等:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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
使用此代码:
1 | isNaN('geoff'); |
请参阅MDN上的
1 2 3 | alert ( isNaN('abcd')); // alerts true alert ( isNaN('2.0')); // alerts false alert ( isNaN(2.0)); // alerts false |
对于要测试的类型Number的值是否为
1 | isNaN(any-Number); |
对于适用于JS中所有类型的通用方法,我们可以使用以下任何一种方法:
对于ECMAScript-5用户:
1 2 3 4 5 6 7 | #1 if(x !== x) { console.info('x is NaN.'); } else { console.info('x is NOT a NaN.'); } |
对于使用ECMAScript-6的人:
1 2 | #2 Number.isNaN(x); |
为了保持ECMAScript 5和6的一致性,我们也可以将此polyfill用于Number.isNan
1 2 3 4 5 6 7 8 9 | #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; } |
请查看本答案了解更多详情。
NaN是一个特殊值,无法像那样进行测试。我只想分享一个有趣的事情就是这个
1 2 3 | var nanValue = NaN; if(nanValue !== nanValue) // Returns true! alert('nanValue is NaN'); |
这仅对NaN值返回true,并且是一种安全的测试方法。绝对应该包含在一个函数中或至少被评论过,因为测试相同的变量是否彼此不相等显然没有多大意义,呵呵。
您应该使用全局
- 它支持跨浏览器
- 有关文档,请参阅isNaN
例子:
1 2 | isNaN('geoff'); // true isNaN('3'); // false |
我希望这能帮到您。
从ES6开始,
1 2 | var a = 3 / 'bar'; Object.is(a, NaN); // true |
要解决
所以不是这样:
1 2 3 4 | parseFloat('1.2geoff'); // => 1.2 isNaN(parseFloat('1.2geoff')); // => false isNaN(parseFloat('.2geoff')); // => false isNaN(parseFloat('geoff')); // => true |
做这个:
1 2 3 4 | Number('1.2geoff'); // => NaN isNaN(Number('1.2geoff')); // => true isNaN(Number('.2geoff')); // => true isNaN(Number('geoff')); // => true |
编辑:我刚刚注意到另一个问题,虽然...传递到
1 2 3 | function definitelyNaN (val) { return isNaN(val && val !== true ? Number(val) : parseFloat(val)); } |
这涵盖了看似一切。我对它的基准测试速度比lodash的
http://jsperf.com/own-isnan-vs-underscore-lodash-isnan
为了清楚起见,我处理了对"非数字"的东西的人类字面解释,并且lodash负责检查是否某些东西是"NaN"的计算机字面解释。
虽然@chiborg的答案是正确的,但还有更多内容需要注意:
1 2 3 4 | parseFloat('1.2geoff'); // => 1.2 isNaN(parseFloat('1.2geoff')); // => false isNaN(parseFloat('.2geoff')); // => false isNaN(parseFloat('geoff')); // => true |
重点是,如果您使用此方法验证输入,结果将相当自由。
所以,是的,你可以使用
简单方案!
非常简单!这里!有这种方法!
1 | function isReallyNaN(a) { return a !== a; }; |
使用简单如下:
1 | if (!isReallyNaN(value)) { return doingStuff; } |
See performance test here using this func vs selected answer
Also: See below 1st example for a couple alternate implementations.
例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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 }))) }; |
1 2 3 4 | table { border-collapse: collapse; } th, td { border: 1px solid; padding: 2px 5px; } .true { color: red; } .false { color: green; } |
1 2 | <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"> <table></table> |
如果您不想使用交替命名的方法,并且希望确保它更全局可用,那么您可以采用几种替代路径来实现。警告这些解决方案涉及更改本机对象,可能不是您的最佳解决方案。请务必小心谨慎,并注意您可能使用的其他库可能依赖于本机代码或类似的更改。
备用实现1:替换Native
1 2 | // Extremely simple. Just simply write the method. window.isNaN = function(a) { return a !==a; } |
替代实施2:附加到数字对象
*建议,因为它也是ECMA 5到6的填充
1 2 3 | Number['isNaN'] || (Number.isNaN = function(a) { return a !== a }); // Use as simple as Number.isNaN(NaN) |
替代解决方案测试是否为空 sub>
我写的一个简单的窗口方法,测试对象是否为空。这有点不同,因为它没有给出物品是否"完全"NaN,但我想我会把它扔掉,因为它在寻找空物品时也可能有用。
1 2 3 4 5 6 7 | /** 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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | ;(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()})))}; |
1 2 3 4 | table { border-collapse: collapse; float: left; } th, td { border: 1px solid; padding: 2px 5px; } .true { color: red; } .false { color: green; } |
1 2 3 | <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"> <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> |
非常深入检查是否为空
最后一个有点深入,甚至检查对象是否充满了空白对象。我确信它有改进的空间和可能的坑,但到目前为止,它似乎捕获了大部分内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | 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()})))}; |
1 2 3 4 | table { border-collapse: collapse; float: left; } th, td { border: 1px solid; padding: 2px 5px; } .true { color: red; } .false { color: green; } |
1 2 3 | <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"> <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,那么您可能希望使用
1 2 3 | isNaN(NaN); // true isNaN(undefined); // true isNaN({}); // true |
因此,在ECMA Script 2015支持的环境中,您可能希望使用
1 | Number.isNaN(parseFloat('geoff')) |
JavaScript中的NaN代表"非数字",虽然它的类型实际上是数字。
1 | typeof(NaN) //"number" |
要检查变量是否具有值NaN,我们不能简单地使用函数isNaN(),因为isNaN()具有以下问题,请参见下文:
1 2 | var myVar ="A"; isNaN(myVar) // true, although"A" is not really of value NaN |
这里真正发生的是myVar被隐式强制转换为一个数字:
1 2 | var myVar ="A"; isNaN(Number(myVar)) // true. Number(myVar) is NaN here in fact |
它实际上是有道理的,因为"A"实际上不是数字。但我们真正想要检查的是myVar是否与NaN值完全相同。
所以isNaN()无法帮助。那我们该怎么做呢?
鉴于NaN是唯一被视为不等于自身的JavaScript值,因此我们可以使用!==检查它与自身的相等性。
1 2 3 4 5 6 7 8 | var myVar; // undefined myVar !== myVar // false var myVar ="A"; myVar !== myVar // false var myVar = NaN myVar !== myVar // true |
总而言之,如果变量!==本身是真的,那么这个变量正好是NaN的值:
1 2 3 4 5 6 7 | function isOfValueNaN(v) { return v !== v; } var myVar ="A"; isNaN(myVar); // true isOfValueNaN(myVar); // false |
我只想分享另一种选择,它不一定比其他人更好,但我认为值得关注:
1 | function customIsNaN(x) { return (typeof x == 'number' && x != 0 && !x); } |
这背后的逻辑是除
我做了一个快速测试,它的性能与
结果
1 2 3 4 5 6 7 8 9 10 | 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 |
如果你想避免破坏
我使用下划线的
1 2 | isNaN(undefined) -> true |
至少,要注意那个问题。
也许这个:
1 2 3 4 5 | function isNaNCustom(value){ return value.toString() === 'NaN' && typeof value !== 'string' && typeof value === 'number' } |
在开箱即用的Node.js中似乎不支持isNaN()。
我一起工作
1 2 | var value = 1; if (parseFloat(stringValue)+"" !=="NaN") value = parseFloat(stringValue); |
1 2 3 4 5 6 | function isNotANumber(n) { if (typeof n !== 'number') { return true; } return n !== n; } |
1 2 3 4 | NaN === NaN; // false Number.NaN === NaN; // false isNaN(NaN); // true isNaN(Number.NaN); // true |
Equality operator (== and ===) cannot be used to test a value against NaN.
查看Mozilla文档全局NaN属性是表示Not-A-Numbe的值
最好的方法是使用'isNaN()',它是用于检查NaN的buit-in函数。所有浏览器支持的方式..
确切的检查方法是:
1 2 3 | //takes care of boolen, undefined and empty isNaN(x) || typeof(x) ==='boolean' || typeof(x) !=='undefined' || x!=='' ? 'is really a nan' : 'is a number' |
是(NaN> = 0)?......"我不知道"。
1 2 3 4 5 | function IsNotNumber( i ){ if( i >= 0 ){ return false; } if( i <= 0 ){ return false; } return true; } |
条件仅在TRUE时执行。
不是假的。
不是"我不知道"。
我在StackOverflow上写了另一个问题的答案,其中另一个问题在
关于
简短的回答
当你想确定你的值是一个正确的数字或??
答案很长
NaN(非数字)是javascript中的怪异全局对象,当某些数学运算失败时经常返回。
您想检查
找出变量是否为
另一个是
但为什么简短的答案有效?
我们来看看。
当您调用
在规范的某处,JavaScript有一个始终为false值的记录,其中包括:
-
NaN - 非数字 -
"" - 空字符串 -
false - 布尔值false -
null - null对象 -
undefined - 未定义的变量 -
0 - 数字0,包括+0和-0
根据IEEE 754,除了!=之外,涉及NaN的所有关系都被评估为假。因此,例如,如果A或B或两者都是NaN,则(A> = B)=假并且(A <= B)=假。
marksyzm的答案很有效,但它不会为
我想出了一个
1 2 3 4 5 6 7 8 9 10 | 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")); |
更新:
我注意到这个代码失败了一些参数,所以我做得更好。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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)); |
找到另一种方式,只是为了好玩。
1 2 3 | function IsActuallyNaN(obj) { return [obj].includes(NaN); } |
规则是:
1 | NaN != NaN |
isNaN()函数的问题是它在某些情况下可能会返回意外结果:
1 2 3 4 5 6 | isNaN('Hello') //true isNaN('2005/12/12') //true isNaN(undefined) //true isNaN('NaN') //true isNaN(NaN) //true isNaN(0 / 0) //true |
检查值是否真的是NaN的更好方法是:
1 2 3 4 5 | function is_nan(value) { return value != value } is_nan(parseFloat("geoff")) |
我创造了这个像魅力一样的小功能。
您可以检查一个数字,而不是检查看似反直觉的NaN。我很确定我不是第一个这样做的人,但我想我会分享。
1 2 3 4 5 6 7 8 9 | function isNum(val){ var absVal = Math.abs(val); var retval = false; if((absVal-absVal) == 0){ retval = true } return retval; } |
MDN的parseFloat页面中提到了另一种解决方案
它提供了一个过滤功能来进行严格的解析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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 |
然后你可以使用
1 | alert("1234567890.".indexOf(String.fromCharCode(mycharacter))>-1); |
这不优雅。但是在尝试了isNAN()后,我找到了这个解决方案,这是另一种选择。在这个例子中我也允许'。'因为我正在掩饰浮动。您也可以将其反转以确保不使用任何数字。
1 | ("1234567890".indexOf(String.fromCharCode(mycharacter))==-1) |
这是单个字符评估,但您也可以遍历字符串以检查任何数字。
只需将结果转换为String并与'NaN'进行比较。
1 2 3 4 | var val = Number("test"); if(String(val) === 'NaN') { console.log("true"); } |
所以我看到了几个回应,
但我只是用:
1 2 3 | function isNaN(x){ return x == x && typeof x == 'number'; } |