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

Pau*_*ite 399 javascript nan

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

parseFloat('geoff') == NaN;

parseFloat('geoff') == Number.NaN;
Run Code Online (Sandbox Code Playgroud)

chi*_*org 553

试试这段代码:

isNaN(parseFloat("geoff"))
Run Code Online (Sandbox Code Playgroud)

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

  • 如果要将空字符串解释为"NaN",则为是.(我不是说你总是这样.) (22认同)
  • 是否需要paseFloat? (8认同)
  • isNaN(parseFloat(“ geoff”))// true`isNaN(parseFloat(“ 10geo”))// false`这有什么用? (3认同)

Jaz*_*zzy 136

我刚刚在" 有效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
Run Code Online (Sandbox Code Playgroud)

在@allsyed评论之前没有意识到这一点,但这是在ECMA规范中:https://tc39.github.io/ecma262/#sec-isnan-number

  • 这不是反直觉的代码,而是NaN. (33认同)
  • 有效但违反直觉.我不想保持这种代码. (24认同)
  • @DanM这不是一个bug,它是NaN的标准IEE754行为.它是如何在CPU中实现的,它是世界上使用浮点数的每种编程语言的预期行为. (18认同)
  • @Tarmil Duly注意到了!这真的很有趣; 我一直认为NaN不平等怪异是一个Javascript的事情. (4认同)
  • NaN ===南; //假 这是javascript中的已知错误.isNan是一种新方法. (2认同)
  • @atilkan - 这不是错误,而是一个功能。`NaN` 不是一个值,它是出现问题的信号。此外,这表明数学运算,包括`===`,不会产生合理的结果。`+"foo" === +undefined` 不应计算为 `true`,而 `+"foo" === +"bar"` 可能会更糟。 (2认同)

rah*_*hul 52

使用此代码:

isNaN('geoff');
Run Code Online (Sandbox Code Playgroud)

请参阅isNaN()MDN上的文档.

alert ( isNaN('abcd'));  // alerts true
alert ( isNaN('2.0'));  // alerts false
alert ( isNaN(2.0));  // alerts false
Run Code Online (Sandbox Code Playgroud)

  • 也许只是我个人的想法,但是当 ```var value = 0/0;``` 和 ```var value2= String("123 131");``` 创建 NaN 值之类的东西时,NaN 的想法会变得令人困惑这个 ```var value3 = "abcd";``` 也是一个 NaN 值。 (2认同)

dop*_*ude 42

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

isNaN(any-Number);
Run Code Online (Sandbox Code Playgroud)

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

对于ECMAScript-5用户:

#1
if(x !== x) {
    console.info('x is NaN.');
}
else {
    console.info('x is NOT a NaN.');
}
Run Code Online (Sandbox Code Playgroud)

对于使用ECMAScript-6的人:

#2
Number.isNaN(x);
Run Code Online (Sandbox Code Playgroud)

为了保持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;
}
Run Code Online (Sandbox Code Playgroud)

请查看本答案了解更多详情.

  • 感谢您不仅使用"isNan()"而是提供完整详细的答案.当我在Google上发现这个问题时,这正是我所寻找的. (6认同)
  • @NickPineda感觉是如此相互,但最终MDN可以这样解释"当isNaN函数的参数不是Number类型时,该值首先被强制转换为Number.然后测试结果值以确定它是否是NAN". (2认同)

Jon*_*lay 16

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

var nanValue = NaN;
if(nanValue !== nanValue) // Returns true!
    alert('nanValue is NaN');
Run Code Online (Sandbox Code Playgroud)

仅对 NaN值返回true ,并且是一种安全的测试方法.绝对应该包含在一个函数中或至少被评论过,因为测试相同的变量是否彼此不相等显然没有多大意义,呵呵.


Jer*_*NER 14

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

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

例子:

 isNaN('geoff'); // true
 isNaN('3'); // false
Run Code Online (Sandbox Code Playgroud)

我希望这能帮到您.


zan*_*ngw 13

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

var a = 3 / 'bar';
Object.is(a, NaN); // true
Run Code Online (Sandbox Code Playgroud)


Bob*_*ave 9

规则是:

NaN != NaN
Run Code Online (Sandbox Code Playgroud)

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

isNaN('Hello')      //true
isNaN('2005/12/12') //true
isNaN(undefined)    //true
isNaN('NaN')        //true
isNaN(NaN)          //true
isNaN(0 / 0)        //true
Run Code Online (Sandbox Code Playgroud)

检查值是否确实为 NaN 的更好方法是:

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

is_nan(parseFloat("geoff"))
Run Code Online (Sandbox Code Playgroud)


mar*_*yzm 8

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

所以不是这样:

parseFloat('1.2geoff'); // => 1.2
isNaN(parseFloat('1.2geoff')); // => false
isNaN(parseFloat('.2geoff')); // => false
isNaN(parseFloat('geoff')); // => true
Run Code Online (Sandbox Code Playgroud)

做这个:

Number('1.2geoff'); // => NaN
isNaN(Number('1.2geoff')); // => true
isNaN(Number('.2geoff')); // => true
isNaN(Number('geoff')); // => true
Run Code Online (Sandbox Code Playgroud)

编辑:我刚刚注意到另一个问题,虽然...假值(和真实的布尔值)传递给Number()返回为0!在这种情况下... parseFloat每次都有效.所以回过头来看:

function definitelyNaN (val) {
    return isNaN(val && val !== true ? Number(val) : parseFloat(val));
}
Run Code Online (Sandbox Code Playgroud)

这涵盖了看似一切.我对它的基准测试速度比lodash慢了90%_.isNaN但是那个并没有覆盖所有的NaN:

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

为了清楚起见,我处理了对"非数字"的东西的人类字面解释,并且lodash负责检查是否某些东西是"NaN"的计算机字面解释.


Rya*_*ith 7

虽然@chiborg的答案是正确的,但还有更多内容需要注意:

parseFloat('1.2geoff'); // => 1.2
isNaN(parseFloat('1.2geoff')); // => false
isNaN(parseFloat('.2geoff')); // => false
isNaN(parseFloat('geoff')); // => true
Run Code Online (Sandbox Code Playgroud)

重点是,如果您使用此方法验证输入,结果将相当自由.

所以,是的,你可以使用parseFloat(string)(或在全数字的情况下,parseInt(string, radix)然后随后用它包裹isNaN(),但要注意数字与其他非数字字符交织在一起的问题).

  • 请注意,只有当字符串**以数字开头**时才会发生这种情况.`parseFloat('test1.2')`将返回`NaN`. (2认同)

SpY*_*3HH 6

简单方案!

非常简单!这里!有这种方法!

function isReallyNaN(a) { return a !== a; };
Run Code Online (Sandbox Code Playgroud)

使用简单如下:

if (!isReallyNaN(value)) { return doingStuff; }
Run Code Online (Sandbox Code Playgroud)

请参阅here使用此func vs的性能测试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
    })))
};
Run Code Online (Sandbox Code Playgroud)
table { border-collapse: collapse; }
th, td { border: 1px solid; padding: 2px 5px; }
.true { color: red; }
.false { color: green; }
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table></table>
Run Code Online (Sandbox Code Playgroud)

如果您不想使用交替命名的方法,并且希望确保它更全局可用,那么您可以采用几种替代路径来实现.警告这些解决方案涉及更改本机对象,可能不是您的最佳解决方案.请务必小心谨慎,并注意您可能使用的其他库可能依赖于本机代码或类似的更改.

备用实现1:替换Native isNaN方法.

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

替代实施2:附加到数字对象
*建议,因为它也是ECMA 5到6的多重填充

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

如果为空,则替代解决方案测试

我写的一个简单的窗口方法,测试对象是否为.这有点不同,因为它没有给出物品是否"完全"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);
})();
Run Code Online (Sandbox Code Playgroud)

例:

;(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()})))};
Run Code Online (Sandbox Code Playgroud)
table { border-collapse: collapse; float: left; }
th, td { border: 1px solid; padding: 2px 5px; }
.true { color: red; }
.false { color: green; }
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)


非常深入检查是否为空

最后一个有点深入,甚至检查对象是否充满了空白对象.我确信它有改进的空间和可能的坑,但到目前为止,它似乎捕获了大部分内容.

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()})))};
Run Code Online (Sandbox Code Playgroud)
table { border-collapse: collapse; float: left; }
th, td { border: 1px solid; padding: 2px 5px; }
.true { color: red; }
.false { color: green; }
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

  • @PaulD.Waite SE用于android.在星系s3上 (2认同)

d2v*_*vid 5

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

isNaN(undefined) 
-> true
Run Code Online (Sandbox Code Playgroud)

至少,要注意这个问题。

  • 我糊涂了。为什么 isNaN 在传递 `undefined` 时会返回 true 是不正确的行为?`undefined` 不是数字是真的,不是吗? (10认同)
  • @Xaxis NaN 不应被视为等同于 undefined,它们都是具有特定和 *不同* 含义的特殊值。考虑一下:我有一个值,但我没有告诉它是什么,也许它是一个数字,也许不是,但是,从您的角度来看,它是未定义的。 (3认同)

Tib*_*org 5

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

function customIsNaN(x) { return (typeof x == 'number' && x != 0 && !x); }
Run Code Online (Sandbox Code Playgroud)

这背后的逻辑是,除了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
Run Code Online (Sandbox Code Playgroud)

如果您想避免损坏的isNaN功能,可能会很有用。


the*_*eye 5

如果您的环境支持ECMAScript 2015,那么您可能希望使用Number.isNaN以确保该值是真的NaN.

问题isNaN是,如果将其与非数字数据一起使用,则应用的混乱规则(根据MDN)很少.例如,

isNaN(NaN);       // true
isNaN(undefined); // true
isNaN({});        // true
Run Code Online (Sandbox Code Playgroud)

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

Number.isNaN(parseFloat('geoff'))
Run Code Online (Sandbox Code Playgroud)

  • 我的环境只支持ECMAScript XP Home Edition :( (7认同)

Viv*_*nde 5

function isNotANumber(n) {
  if (typeof n !== 'number') {
    return true;
  } 
  return n !== n;
}
Run Code Online (Sandbox Code Playgroud)


Yuc*_*uci 5

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

typeof(NaN) // "number"
Run Code Online (Sandbox Code Playgroud)

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

var myVar = "A";
isNaN(myVar) // true, although "A" is not really of value NaN
Run Code Online (Sandbox Code Playgroud)

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

var myVar = "A";
isNaN(Number(myVar)) // true. Number(myVar) is NaN here in fact
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

var myVar = NaN
myVar !== myVar // true
Run Code Online (Sandbox Code Playgroud)

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

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

var myVar = "A";
isNaN(myVar); // true
isOfValueNaN(myVar); // false
Run Code Online (Sandbox Code Playgroud)