【问题标题】:How do you check that a number is NaN in JavaScript?如何在 JavaScript 中检查一个数字是否为 NaN?
【发布时间】:2011-02-08 18:53:55
【问题描述】:

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

parseFloat('geoff') == NaN;

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

【问题讨论】:

  • 如果您的实际目标是检查数字,则值得一读:stackoverflow.com/questions/18082/…
  • @Gothdo:当然,但我确实问过如何检查 number 是否为 NaN,而不是任何值。
  • @PaulD.Waite 是的,但是当谷歌搜索“如何在 javascript 中检查变量是否为 nan”之类的内容时,很多人会来到这里。
  • PaulD.Waite 我同意你的观点,但我和@Gothdo 有同样的担忧。许多人提出这个问题的目的是“如何检查 JS 中的值是否为 NaN”。您可以查看 mjohnsonengr 对 the same answer 的评论。顺便说一句,我也标记了This question 以供版主注意。

标签: javascript nan


【解决方案1】:

isNaN() 函数确定一个值是否为 NaN。因为 isNaN 函数内部的强制转换可能令人惊讶,所以您也可以使用 Number.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
isNaN(null) //false

isNaN 函数的便利性 与 JavaScript 中的所有其他可能值不同,不能使用相等运算符(== 和 ===)将值与 NaN 进行比较以确定该值是否为 NaN,因为 NaN == NaN 和 NaN = == NaN 评估为假。 isNaN() 函数为 NaN 提供了方便的相等性检查。

【讨论】:

    【解决方案2】:
    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
    

    【讨论】:

      【解决方案3】:

      规则是:

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

      【讨论】:

        【解决方案4】:

        也许还有这个:

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

        【讨论】:

          【解决方案5】:

          所以我看到了一些对此的回应,

          但我只是使用:

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

          【讨论】:

          • 不应该是return x != x && typeof x === 'number'吗?
          【解决方案6】:

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

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

          条件仅在 TRUE 时执行。

          不是FALSE

          不在“我不知道”。

          【讨论】:

          • 如果你明确地寻找 NaN 值而不是寻找相反的值,这不是很有用
          【解决方案7】:

          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
          

          【讨论】:

            【解决方案8】:

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

            【讨论】:

            • 感谢帮助!!
            【解决方案9】:
            alert("1234567890.".indexOf(String.fromCharCode(mycharacter))>-1);
            

            这并不优雅。但是在尝试了 isNAN() 之后,我找到了这个解决方案,这是另一种选择。在这个例子中,我还允许使用 '.'因为我正在掩盖浮动。您也可以将其反转以确保不使用任何数字。

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

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

            【讨论】:

              【解决方案10】:

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

              更新: 我注意到这段代码在某些参数上失败了,所以我把它做得更好。

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

              【讨论】:

              【解决方案11】:

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

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

              【讨论】:

                【解决方案12】:

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

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

                为 NaN 值返回 true,是一种安全的测试方式。绝对应该被包裹在一个函数中或者至少被注释掉,因为测试同一个变量是否不相等显然没有多大意义,呵呵。

                【讨论】:

                • 这不是一个完全可靠的方法。根据规格。 variable !== variable 是检查 NaN 的最可靠方法
                • 在此查看我上面的答案 ^
                【解决方案13】:

                我刚刚在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

                【讨论】:

                • 有效但违反直觉。我不想维护这种代码。
                • 反直觉的不是代码,而是 NaN。
                • @DanM 这不是错误,它是 NaN 的标准 IEE754 行为。这是它在 CPU 中的实现方式,也是世界上每种使用浮点数的编程语言的预期行为。
                • @Tarmil 注意到了!这真的很有趣。我一直认为 NaN 不等式的怪异是 Javascript 的事情。
                • @atilkan - 这不是一个错误,而是一个功能。NaN 不是一个值,它是出现问题的信号。此外,这是一个信号,包括=== 在内的数学运算不会产生合理的结果。 +"foo" === +undefined 不应该评估为 true+"foo" === +"bar" 可能会更糟。
                【解决方案14】:

                只需将结果转换为字符串并与 'NaN' 进行比较。

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

                【讨论】:

                  【解决方案15】:

                  简单的解决方案!

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

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

                  使用简单如下:

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

                  See performance test here 使用这个函数 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
                      })))
                  };
                  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 的 poly-fill

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

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

                  我写了一个简单的窗口方法来测试对象是否为。有点不同,它不会给出是否项目是“完全”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()})))};
                  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>

                  【讨论】:

                  • @PaulD.Waite 也许是它的这个应用程序,但我没有看到一个可接受的答案。事实上,我只看到大约 5 个答案,但我看到它说有 15 个
                  • 你用的是什么应用?
                  • @PaulD.Waite 安卓版的 SE。在 Galaxy s3 上
                  • 啊哈。我没有查看自己的应用程序,但这里有一个已接受答案的链接:stackoverflow.com/a/2652335/20578
                  • @PaulD.Waite 啊,我明白了。我想,直接回答问题本身就足够了。我在另一个问题上发布了我的答案,这个问题完全与“JS 方法来检查是否'真的'NaN”有关,因为isNaN 不可靠。我在那里被评论并告诉这个问题更适合我的答案,因此将它移到这里。只需将一些与此问题相关的有用/有用的东西放在那里,这些东西会在 Google 搜索手头的问题时弹出,is it NaN?。附带说明一下,我的答案比选定的答案更准确。
                  【解决方案16】:

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

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

                  【讨论】:

                    【解决方案17】:

                    具体检查方法是:

                    //takes care of boolen, undefined and empty
                    
                    isNaN(x) || typeof(x) ==='boolean' || typeof(x) !=='undefined' || x!=='' ? 'is really a nan' : 'is a number'
                    

                    【讨论】:

                      【解决方案18】:

                      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

                      【讨论】:

                        【解决方案19】:

                        要测试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了解更多详情。

                        【讨论】:

                        • 感谢您不仅使用“isNan()”,还提供了完整详细的答案。这正是我在 Google 上发现这个问题时所寻找的。​​span>
                        • ".... 对上述情况给出了错误的结果" 我不会说错,只是不同,因为全局 isNaN 将参数转换为数值优先。
                        • @FelixKling 请检查更新的答案。谢谢。
                        • isNaN("lorem ipsum"); //真正的 ES5 让我大吃一惊
                        • @NickPineda 感觉如此相互,但最终MDN可以这样解释“当isNaN函数的参数不是Number类型时,首先将值强制为Number。结果值然后进行测试以确定它是否为 NaN。”
                        【解决方案20】:

                        试试这个代码:

                        isNaN(parseFloat("geoff"))
                        

                        要检查 any 值是否为 NaN,而不仅仅是数字,请参见此处:How do you test for NaN in Javascript?

                        【讨论】:

                        • 是否需要paseFloat?
                        • 如果您希望将空字符串解释为NaN,那么可以。 (我并不是说你总是会这样做。)
                        • 如果我是你,我会将它分配给一个变量,然后使用条件变量!== 变量。正如规范中所述tc39.github.io/ecma262/#sec-isnan-number
                        • isNaN(parseFloat("geoff")) // true isNaN(parseFloat("10geo")) // false 这有什么用?
                        • 这对于尝试w3schools.com/jsref/jsref_isnan.asp 也很有用
                        【解决方案21】:

                        使用此代码:

                        isNaN('geoff');
                        

                        isNaN() docs on MDN

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

                        【讨论】:

                        • 也许只有我一个人,但是当 var value = 0/0;var value2= String("123 131"); 创建 NaN 值时,NaN 的概念会变得令人困惑,而像 var value3 = "abcd"; 这样的东西也是一个 NaN 值。
                        • @NickPineda 为什么?
                        【解决方案22】:

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

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

                        【讨论】:

                        【解决方案23】:

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

                        看看Mozilla Developer Network关于NaN


                        简答

                        当你想确定你的值是一个正确的数字时,只需使用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 有一条总是错误值的记录,其中包括:

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

                        【讨论】:

                        • “判断变量是否为 NaN 的唯一简单方法是全局函数 isNaN()”——不正确;还有另一种简单的方法:var xIsNaN = x !== x; 只有当 x 是 NaN 时才会产生 true。
                        【解决方案24】:

                        如果您的环境支持 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 Script 2015 支持的环境中,您可能希望使用

                        Number.isNaN(parseFloat('geoff'))
                        

                        【讨论】:

                        • 我的环境只支持ECMAScript XP Home Edition :(
                        • @PaulD.Waite (我希望你的意思是 IE 6 :D) 没问题 :-) 请记住 isNaN 可能会给你带来麻烦并记住在 ECMAScript 2015 环境中使用 Number.isNaN : -)
                        【解决方案25】:
                        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

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

                        【讨论】:

                          【解决方案26】:

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

                          【讨论】:

                            【解决方案27】:

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

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

                            例子:

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

                            希望对你有帮助。

                            【讨论】:

                            • 是的,isNaN('') //falseparseInt('') //NaNnull 也是如此。
                            【解决方案28】:

                            要解决'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() 的错误值(并且作为真正的布尔值)返回为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”的计算机字面解释。

                            【讨论】:

                              【解决方案29】:

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

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

                              这背后的逻辑是除了0NaN之外的每个数字都被转换为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 函数,可能会变得有用。

                              【讨论】:

                                【解决方案30】:

                                虽然@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”不是真正有效的数字字符串?
                                • 请注意,这只发生在字符串以数字开头时。 parseFloat('test1.2') 将返回 NaN
                                猜你喜欢
                                • 2014-11-09
                                • 2016-11-14
                                • 2021-05-30
                                • 2013-08-22
                                • 2012-07-11
                                • 2011-04-04
                                • 2018-02-03
                                相关资源
                                最近更新 更多