代码之家  ›  专栏  ›  技术社区  ›  Paul D. Waite

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

  •  355
  • Paul D. Waite  · 技术社区  · 15 年前

    我只在firefox的javascript控制台上尝试过,但以下两条语句都没有返回true:

    parseFloat('geoff') == NaN;
    
    parseFloat('geoff') == Number.NaN;
    
    30 回复  |  直到 6 年前
        1
  •  506
  •   Community CDub    8 年前

    试试这个代码:

    isNaN(parseFloat("geoff"))
    

    用于检查是否 任何 值为NaN,而不仅仅是数字,请参见以下内容: How do you test for NaN in Javascript?

        2
  •  128
  •   Jazzy    8 年前

    我刚在书中遇到这种技巧 Effective 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

        3
  •  48
  •   Michał Perłakowski    9 年前

    使用此代码:

    isNaN('geoff');
    

    isNaN() docs on MDN .

    alert ( isNaN('abcd'));  // alerts true
    alert ( isNaN('2.0'));  // alerts false
    alert ( isNaN(2.0));  // alerts false
    
        4
  •  39
  •   Community CDub    8 年前

    对于类型的值 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 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;
    }
    

    请检查 This Answer 了解更多详细信息。

        5
  •  16
  •   Jonathan    8 年前

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

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

    这返回真值 只有 对于NaN值,是一种安全的测试方法。当然应该用一个函数包装,或者至少是注释,因为测试同一个变量是否不相等显然没有多大意义,呵呵。

        6
  •  14
  •   ultimatetechie    11 年前

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

    • 支持跨浏览器
    • isNaN 用于文档

    实例:

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

    我希望这对你有帮助。

        7
  •  12
  •   zangw    9 年前

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

    var a = 3 / 'bar';
    Object.is(a, NaN); // true
    
        8
  •  8
  •   marksyzm    11 年前

    解决问题的方法 '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
    

    编辑:不过我注意到了另一个问题…传递到 编号() 返回为 0 !在这种情况下…ParseFloat每次都工作。所以回到这个问题上来:

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

    这似乎涵盖了一切。我把它定为比洛达什慢90%。 _.isNaN 但这一条并没有涵盖所有的NAN:

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

    为了清楚起见,我负责人对“非数字”的文字解释,而Lodash负责计算机文字解释,以检查是否有“Nan”。

        9
  •  7
  •   Ryan Griffith    11 年前

    虽然@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() 但要注意数字与其他非数字字符交织在一起的gotcha。

        10
  •  6
  •   Community CDub    8 年前

    简单的解决方案!

    真的非常简单!在这里!有这个方法!

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

    简单用法如下:

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

    See performance test 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)
    

    替代解决方案 测试是否为空

    一个简单的窗口方法,我编写了这个测试,如果对象是 空的 . 有点不同,如果物品是 “正”南 但我想我会把它扔掉,因为它在寻找空的物品时可能也很有用。

    /** 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()})))};
    表边框折叠:折叠;浮动:左;
    th,td边框:1px实心;填充:2px 5px;
    .真颜色:红色;
    .假颜色:绿色;
    <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>值类型</th><th>bool返回</th></tr></thead></table>
    <table id=“t2”><thead><tr><th colspan=“2”>isreallynan()</th></tr></thead><thead><tr><th>值类型</th><th>bool返回</th></tr></thead></table>
        11
  •  5
  •   thefourtheye    9 年前

    如果您的环境支持EcmaScript 2015 ,那么您可能想使用 Number.isNaN 以确保该值 NaN .

    问题在于 isNaN 是, if you use that with non-numeric data there are few confusing rules (as per MDN) are applied. 例如,

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

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

    Number.isNaN(parseFloat('geoff'))
    
        12
  •  4
  •   Paul D. Waite    12 年前

    我用 underscore's isNaN 函数,因为在javascript中:

    isNaN(undefined) 
    -> true
    

    至少,要意识到这一点。

        13
  •  4
  •   Yuci    7 年前

    javascript中的nan代表“不是数字”,尽管它的类型实际上是数字。

    typeof(NaN) // "number"
    

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

    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
    
        14
  •  3
  •   Stephan Ahlf    12 年前

    node.js开箱即用似乎不支持isnan()。
    我和

    var value = 1;
    if (parseFloat(stringValue)+"" !== "NaN") value = parseFloat(stringValue);
    
        15
  •  3
  •   Tiborg gvelasquez85    11 年前

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

    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 功能。

        16
  •  3
  •   Vivek Munde    7 年前

    function isNotANumber(n) {
      if (typeof n !== 'number') {
        return true;
      } 
      return n !== n;
    }
        17
  •  2
  •   MURATSPLAT    10 年前
    NaN === NaN;        // false
    Number.NaN === NaN; // false
    isNaN(NaN);         // true
    isNaN(Number.NaN);  // true
    

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

    Mozilla Documentation The global NaN property is a value representing Not-A-Numbe

    最好的方法是使用内置函数“is nan()”来检查NaN。所有浏览器都支持这种方式。

        18
  •  2
  •   Nishanth Matha miguel savignano    9 年前

    确切的检查方法是:

    //takes care of boolen, undefined and empty
    
    isNaN(x) || typeof(x) ==='boolean' || typeof(x) !=='undefined' || x!=='' ? 'is really a nan' : 'is a number'
    
        19
  •  2
  •   Pierfrancesco    7 年前

    也可能是这样:

    function isNaNCustom(value){
        return value.toString() === 'NaN' && 
               typeof value !== 'string' && 
               typeof value === 'number'
    }
    
        20
  •  1
  •   Ronald Davis    10 年前

    根据IEEE754,所有涉及NAN的关系都被认为是错误的,除了!=因此,例如,(a>=b)=false和(a<=b)=false,如果a或b或两者都是NaN。

        21
  •  1
  •   Community CDub    8 年前

    我把这个答案写在另一个问题上 StackOverflow 其他人什么时候检查 NaN == null 但后来它被标记为副本,所以我不想浪费我的工作。

    Mozilla Developer Network 关于 NaN .


    简短回答

    只使用 distance || 0 当您想确定您的值是正确的数字或 isNaN() 检查一下。

    长回答

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

    你想检查一下 n=空 这结果 false . 霍维尔甚至 NaN == NaN 结果与 .

    找出变量是否为 是全局函数 ISNN() .

    另一个是 x !== x 只有当x是NaN时才是这样。(感谢提醒@raphael schweikert)

    但是为什么这个简短的回答有效呢?

    让我们来查一下。

    当你打电话 NaN == false 结果是 一样 NaN == true .

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

    • 非数字
    • "" -空字符串
    • -布尔值错误
    • null -空对象
    • undefined -未定义的变量
    • 0 -数字0,包括+0和-0
        22
  •  1
  •   Zzy    9 年前

    中提到了另一个解决方案 MDN's parseFloat page

    它提供了一个过滤函数来进行严格的解析

    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

        23
  •  1
  •   Billy Hallman    9 年前

    我创造了这个小功能,就像一个魅力。 不是检查似乎是反直觉的NaN,而是检查一个数字。我很肯定我不是第一个这样做的,但我想我会分享。

    function isNum(val){
        var absVal = Math.abs(val);
        var retval = false;
        if((absVal-absVal) == 0){
            retval = true
        }
    
        return retval;
    }
    
        24
  •  1
  •   Madhukar Kedlaya    8 年前

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

    function IsActuallyNaN(obj) {
      return [obj].includes(NaN);  
    }
    
        25
  •  1
  •   adddff    8 年前

    Marksyzm的回答很好,但不会返回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"));

    更新: 我注意到这个代码在某些参数上失败了,所以我改进了它。

    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));
        26
  •  1
  •   Peter S McIntyre    7 年前
    alert("1234567890.".indexOf(String.fromCharCode(mycharacter))>-1);
    

    这不优雅。但是在尝试isnan()之后,我得到了另一种解决方案。在这个示例中,我还允许使用“.”,因为我对float进行了屏蔽。您还可以反转此选项以确保不使用任何数字。

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

    这是一个单字符的计算,但是您也可以通过一个字符串来检查是否有任何数字。

        27
  •  1
  •   KANJICODER    7 年前

    (南& GT;=0) ?……” 我不知道 “。

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

    条件仅在以下情况下执行 真的 .

    不在 错误的 .

    “不” 我不知道 “。

        28
  •  1
  •   Bob Slave    6 年前

    规则是:

    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"))
    
        29
  •  0
  •   Sachith Muhandiram    8 年前

    只需将结果转换为字符串并与“nan”进行比较。

    var val = Number("test");
    if(String(val) === 'NaN') {
       console.log("true");
    }
    
        30
  •  -1
  •   Shawn    7 年前

    所以我看到了一些回应,

    但我只是用:

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