在javascript中将NaN转换为0


238

没有if语句可以将NaN值转换为0:

if (isNaN(a)) a = 0;

每次检查我的变量都非常烦人。


4
难道您不能将其倒入功能中吗?
the_drow 2011年

这只能是20个字符,这是什么问题?
Rusty Fausak 2011年

1
function noNaN( n ) { return isNaN( n ) ? 0 : n; }然后就noNaN( a )
森那维达斯

1
@rfausak通常,您不想重复自己(请参阅DRY)。如果多次需要某种功能,则首选专用功能。
森那维达斯

Answers:


575

你可以这样做:

a = a || 0

...这会将a的“ falsey”值转换为0

“假”值是:

  • false
  • null
  • undefined
  • 0
  • "" (空字符串)
  • NaN (不是数字)

如果您愿意,也可以这样:

a = a ? a : 0;

...将具有与上述相同的效果。


如果要测试的不仅仅是NaN,则可以执行相同的操作,但首先进行toNumber转换。

a = +a || 0

这使用一元+运算符尝试转换a为数字。这具有将数字字符串等内容转换为数字的附加好处'123'

唯一出乎意料的事情是,如果有人传递了可以成功转换为数字的数组:

+['123']  // 123

在这里,我们有一个具有单个成员的数组,该成员是数字字符串。它将成功转换为数字。


将验证转换为功能的想法很好,但是这更优雅。
陶巴氏

1
@Bakudan:好点。我以为OP只关心特定的NaN价值。这不能作为对所有非数字值的测试。尽管我们可以先尝试toNumber转换。我会更新。
user113716 2011年

...啊,是因为标题“将NaN转换为0”。无论如何,现在涵盖了两种方式。
user113716 2011年

2
谢谢队友,为我自己选择并修改了一下a = a * 1 || 0
某人

太棒了 谢谢
Apit John Ismail

32

使用双波浪号(双​​按位NOT)- ~~在JavaScript中做了一些有趣的事情。例如,您可以使用它代替Math.floor甚至替代它parseInt("123", 10)!网上已经对此进行了很多讨论,因此我不会在这里介绍它的工作原理,但是如果您感兴趣的话:JavaScript中的“双波浪号”(~~)运算符是什么?

我们可以利用双波浪号的此属性将其转换NaN为数字,并且很高兴该数字为零!

console.log(~~NaN); // 0


1
谢谢,我不知道这个~~在所有的,我只是用它的旁边parseFloat(),像这样:~~parseFloat($variable);。非常整洁:) +1
伦斯·提尔曼


4

更简单有效的方法:

function getNum(val) {
   val = +val || 0
   return val;
}

...这会将a的“ falsey”值转换为0

“假”值是:

  • false
  • null
  • undefined
  • 0
  • "" (空字符串)
  • NaN (不是数字)

1
有趣!只是想知道当val可以为负值时它将如何反应。据我测试,这没有什么问题,但以防万一……
Luciano

2

与其将它们塞在一起以使您可以继续,不如不备份并想知道为什么首先遇到NaN?

如果操作的任何数字输入为NaN,则输出也将为NaN。这就是当前IEEE浮点标准的工作方式(不仅仅是Javascript)。该行为是有充分理由的:其根本目的是防止您使用假结果而不意识到它是假的。

NaN的工作方式是,如果在某些子操作中出错(在较低级别生成NaN),最终结果将是NaN,即使您将自己立即识别为错误,错误处理逻辑(可能是抛出/捕获?)尚未完成。

NaN作为算术计算的结果 始终表示在算术细节方面出现了问题。这是计算机说“这里需要调试”的一种方式。与其找到某种方法来继续以几乎不可能的数字继续下去(真的是0,是您想要的吗?),不如找出问题并加以解决。

Javascript中的一个常见问题是,如果给定一个毫无意义的参数,两者parseInt(...)parseFloat(...)都会返回NaN(null''等等)。在最低级别(而不是更高级别)上解决问题。这样一来,整个计算的结果就有很大的道理,而您并没有用魔术数(0或1或其他值)代替整个计算的结果。((parseInt(foo.value)|| 0)的技巧仅适用于总和,而不适用于乘积-对于您希望默认值为1而不是0的乘积,但如果指定的值确实为0,则无效。)

也许为了便于编码,您希望函数从用户处检索一个值,将其清理,并在必要时提供默认值,例如:

function getFoobarFromUser(elementid) {
        var foobar = parseFloat(document.getElementById(elementid).innerHTML)
        if (isNaN(foobar)) foobar = 3.21;       // default value
        return(foobar.toFixed(2));
}

2

怎么样一个正则表达式

function getNum(str) {
  return /[-+]?[0-9]*\.?[0-9]+/.test(str)?parseFloat(str):0;
}

下面的代码将忽略NaN以便计算正确输入的数字


2

如果尝试使用parseInt,则使用isNaN的方法不起作用,例如:

parseInt("abc"); // NaN
parseInt(""); // NaN
parseInt("14px"); // 14

但是在第二种情况下isNaN会产生false(即空字符串是一个数字)

n="abc"; isNaN(n) ? 0 : parseInt(n); // 0
n=""; isNaN(n) ? 0: parseInt(n); // NaN
n="14px"; isNaN(n) ? 0 : parseInt(n); // 14

总之,isNaN将空字符串视为有效数字,但parseInt则不将其视为有效数字。在OSX Mojave上通过Safari,Firefox和Chrome进行了验证。


1
一个显而易见的解决方案是有点麻烦,请在parseInt之后而不是在NaNa(parseInt(n))之前检查NaN?parseInt(n):0; //两次调用parseInt :(
David Crowe,

1
该评论应该是您的答案的开始!
frandroid

一种更有效的解决方案假定空字符串是唯一的异常:n ==“” || isNaN(n)吗?0:parseInt(n); (但是,如果还有其他字符串呢?)
David Crowe

1
var i = [NaN, 1,2,3];

var j = i.map(i =>{ return isNaN(i) ? 0 : i});

console.log(j)

[0,1,2,3]


0

使用用户113716解决方案,这很好地避免了所有这些问题,否则,我已经实现了这种方式,可以根据文本框单位和文本框数量计算小计文本框。

在单位和数量文本框中写入非数字的过程中,它们的值将被零替换,因此最终发布的用户数据中不会有非数字。

     <script src="/common/tools/jquery-1.10.2.js"></script>
     <script src="/common/tools/jquery-ui.js"></script>

     <!----------------- link above 2 lines to your jquery files ------>





    <script type="text/javascript" >
    function calculate_subtotal(){

    $('#quantity').val((+$('#quantity').val() || 0));
    $('#unit').val((+$('#unit').val() || 0));

    var  calculated = $('#quantity').val() * $('#unit').val() ;
    $('#subtotal').val(calculated);


    }
    </script>


      <input type = "text" onChange ="calculate_subtotal();" id = "quantity"/>
      <input type = "text" onChange ="calculate_subtotal();" id = "unit"/>
      <input type = "text" id = "subtotal"/>

0

请尝试这个简单的功能

var NanValue = function (entry) {
    if(entry=="NaN") {
        return 0.00;
    } else {
        return entry;
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.