【问题标题】:Javascript Checking for NaN - Results not as expectedJavascript 检查 NaN - 结果与预期不符
【发布时间】:2012-11-16 06:38:16
【问题描述】:

我有一个通过 ajax 读取数字的应用程序,该数字是十六进制的,我对其进行解析并转换为十进制。

这些数字是通过无线串行链路输入的,并不是 100% 可靠的,所以我需要在开始处理数据之前检查它们。例如,数字采用****025781610403e5**** 的形式。 **** 只是检查我过去在非基于 Web 的项目中使用的数字的开始和结束的一种方式,并且可以更改。

最后我的问题是:作为错误检查的一部分,我想我会检查 NaN,因为我在测试时确实遇到了 NaN 错误,但是 *1234 给出了一个肯定的 NaN 12**34 没有,为什么那?我还能做些什么来测试?

这是我使用的一些代码,请注意我对 javascript 相当陌生。

function readSliceConvert()
{
    functionReadForm()
    testVal = hexString.slice(4,18);
    document.getElementById("battDb4").innerHTML=testVal;
    testNum1 = h2d(testVal)
    document.getElementById("battDb5").innerHTML=testNum1.toString();
    testNum2 = parseInt(testVal);
    document.getElementById("battDb6").innerHTML=testNum2.toString();
    if (isNaN(testNum2))
    {
        errorCount++;
        document.getElementById("battDb3").innerHTML=errorCount.toString();
        document.getElementById("battDb4").innerHTML=testVal;

        return;
    }
}

【问题讨论】:

  • isNaN('12**34') === true & isNaN('*1234') === true
  • isNaN('12**34'); 返回 true,您还有其他问题。

标签: javascript nan


【解决方案1】:

那是因为你使用的是parseInt,当它可以解析的字符串开头有一些数字时,它会默默地忽略字符串末尾的字符。

我不知道您的h2d 函数在做什么,但似乎您正在将十六进制字符串转换为数字,然后转换为十进制形式的字符串,然后再转换回数字。我看不出解析十六进制字符串的输出不能是数字的任何原因。

比如这样,解析失败返回null:

function h2i(str) {
  var num = 0;
  var digits = "0123456789abcdef";
  str = str.toLowerCase();
  for (var i = 0; i < str.length; i++) {
    var n = digits.indexOf(str.substr(i, 1));
    if (n == -1) return null;
    num = num * 16 + n;
  }
  return num;
}

演示:http://jsfiddle.net/Guffa/6yAaP/

用法:

testVal = hexString.slice(4,18);
document.getElementById("battDb4").innerHTML = testVal;
testNum = h2i(testVal)
document.getElementById("battDb5").innerHTML = testNum.toString();
if (testNum == null)
{
  errorCount++;
  document.getElementById("battDb3").innerHTML = errorCount.toString();
  document.getElementById("battDb4").innerHTML = testVal;
  return;
}

【讨论】:

  • 感谢代码示例我正在尝试这个,不太确定发生了什么,但我说我是新手。
  • @Simon_A:我在上面添加了一个使用示例,希望对您有所帮助。
【解决方案2】:

你知道 parseInt() 是做什么的吗?

来自MDN

parseInt 是一个顶级函数,不与任何 对象。

parseInt 函数将其第一个参数转换为字符串,解析 它,并返回一个整数或 NaN。如果不是 NaN,则返回值将 是第一个参数的十进制整数表示形式 指定基数(基数)中的数字。例如,基数为 10 表示从十进制数、8 位八进制数、16 位十六进制数转换, 等等。对于 10 以上的基数,字母表中的字母表示 大于 9 的数字。例如,对于十六进制数(基数 16),使用 A 到 F。

如果 parseInt 在 指定的基数,它会忽略它以及所有后续字符和 返回解析到该点的整数值。 parseInt 截断 数字到整数值。允许前导和尾随空格。

在控制台中运行代码

console.log( parseInt("12**34",10) );  

所以你正在对一个数字运行 isNaN,因为 parseInt 返回 12。

当您将 * 作为第一个字符时,没有要返回的前导数字。

console.log( parseInt("*1234",10) );  

【讨论】:

  • 谢谢你,我刚刚了解了console.log的作用,我说我是新手;)
【解决方案3】:

您看到了奇怪的行为,因为 isNan is broken(有关详细信息,请参阅 mozilla 文档)。

测试数据格式是否正确的更好方法是使用快速正则表达式,例如serial.test(/^\d+$/),如果整个序列号完全是数字,它将成功,或者如果序列号是四个星号,则serial.test(/^\*{4}\d+\*{4}$/) 将成功,后跟一个或多个数字,后跟另外四个星号。

更新:@Guffa 的答案是正确的,应该被接受,但我将把它留在这里,因为我认为从大局来看有一个有效的论点,你可以更好地完成你想要用正则表达式做的事情.

在字符串上运行test 会执行提供的正则表达式,如果匹配字符串则返回true

正则表达式只是描述文本的模式,它可以非常复杂,也可以像我给出的示例一样简单(\d+ 表示匹配一个数字(\d)一次或多次(+),字符串开头 (^) 和结尾 ($) 的锚点,表示我们想要匹配整个字符串,而不仅仅是其中的一部分。它们非常有用,所以几乎可以肯定值得花时间学习它们如何工作的基础知识,并随着时间的推移扩展您的知识。regular-expressions.info 上有一个很棒的教程可以让您立即开始。

【讨论】:

  • 不,isNaN 只是在您不知道要发送什么内容时给出令人困惑的结果的意义上被破坏。在这种情况下,它始终是parseInt 的结果,因此值的类型是已知的,使用isNan 没有问题。
  • 我不会说 isNaNbroken===== are broken 它只是有你需要的怪癖了解。
  • 在他的代码中错过了parseInt,很好。我仍然认为他的技术不是最好的,但你是对的。
  • @Chad 也许,但是怪癖和错误之间有一条很好的界限。 Mozilla 将其描述为已损坏,并且其行为已损坏/古怪到有时无法预测,因此我倾向于建议不要这样做。
  • @Kelvin Mackay serial.test(/^*{4}\d+*{4}$/) - 这看起来不错/有趣,但我不知道它在做什么,或者它是如何而是这样做。
猜你喜欢
  • 1970-01-01
  • 2021-02-19
  • 1970-01-01
  • 2020-10-19
  • 2017-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-19
相关资源
最近更新 更多