为什么isNaN("")等于false

IVR*_*ger 154 javascript nan

我有一个简单的问题(我希望!).在JS中,为什么isNaN(" ")评估为false,但false评估为true?

我正在对文本输入字段执行数值运算,并检查字段是否为空,""或NaN.当有人在场中输入少量空格时,我的验证在所有三个空格中都失败了,我很困惑为什么它超过了isNAN检查.

谢谢!

Ant*_*ley 149

JavaScript将空字符串解释为0,然后无法通过isNAN测试.您可以首先在字符串上使用parseInt,它不会将空字符串转换为0.结果应该是失败的isNAN.

  • 但是parseInt("123abcd")返回123,这意味着isNaN(parseInt("123abcd"))将返回false,而它应该返回true! (48认同)
  • 那么怎么样(IsNaN(string)|| isNaN(parseInt(string))) (9认同)
  • 解释`isNaN(arg)`有两个步骤.1)将arg转换为数字,2)检查该数字是否为数值"NaN".这有助于我更好地理解它. (5认同)
  • @Antonio_Haley请稍等,我不明白。如果“ JavaScript将空字符串解释为0”,为什么parseInt(“”)返回NaN? (2认同)
  • @Jean-François你是对的,更正确的说法是“isNaN 将空字符串解释为 0”,而不是 JavaScript 本身。 (2认同)

Nic*_*rdi 80

您可能会发现这个令人惊讶或者可能没有,但这里有一些测试代码可以向您展示JavaScript引擎的古怪.

document.write(isNaN("")) // false
document.write(isNaN(" "))  // false
document.write(isNaN(0))  // false
document.write(isNaN(null)) // false
document.write(isNaN(false))  // false
document.write("" == false)  // true
document.write("" == 0)  // true
document.write(" " == 0)  // true
document.write(" " == false)  // true
document.write(0 == false) // true
document.write(" " == "") // false
Run Code Online (Sandbox Code Playgroud)

所以这意味着

" " == 0 == false
Run Code Online (Sandbox Code Playgroud)

"" == 0 == false
Run Code Online (Sandbox Code Playgroud)

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

玩得开心 :)

  • @Kooilnc事实上,NaN!= NaN实际上是一次不错的选择.我的想法是,NaN几乎总是计算的结果与程序员的预期不同,并且假设"错误"的两个计算结果相同是非常危险的. (10认同)
  • +1精彩帖子.你可以添加三等于(===和!==)运算符如何适合这里吗? (5认同)
  • 你应该尝试NaN === NaN或NaN == NaN ;-)我不知道这一切是否意味着javascript引擎是古怪的,或者javascript对于古怪的程序员来说是坏事. (2认同)
  • @Kooilnc甚至没有从javascript的古怪中拿走,但这些NaN只是遵守IEEE 754浮点标准.您可以像往常一样在大W上阅读所有关于它的信息:http://en.wikipedia.org/wiki/NaN (2认同)

Raf*_*ael 16

要更好地理解它,请打开第43页的Ecma-Script规范pdf "ToNumber应用于字符串类型"

如果字符串具有数字语法,可以包含任意数量的空格字符,则可以将其转换为数字类型.空字符串的计算结果为0.此外,字符串'Infinity'应该给出

isNaN('Infinity'); // false
Run Code Online (Sandbox Code Playgroud)


ben*_*wey 15

尝试使用:

alert(isNaN(parseInt("   ")));
Run Code Online (Sandbox Code Playgroud)

要么

alert(isNaN(parseFloat("    ")));
Run Code Online (Sandbox Code Playgroud)

  • 嗨,先生,isNaN(parseInt("123a")):将返回123,所以如果字符串包含aplha数字,你的解决方案将无效 (2认同)

dop*_*ude 6

MDN你面临的问题的原因

当isNaN函数的参数不是Number类型时,该值首先被强制转换为Number.然后测试得到的值以确定它是否是NaN.

您可能需要查看以下综合答案,其中也包含NaN比较的相等性.

如何测试JavaScript变量是否是 NaN


Jam*_*lly 6

不完全正确的答案

安东尼奥·黑利 ( Antonio Haley)在这里的高度赞成和接受的答案做出了错误的假设,即此过程通过 JavaScript 的parseInt功能:

您可以在字符串上使用 parseInt ......结果应该失败 isNAN。

我们可以很容易地用字符串反驳这个说法"123abc"

parseInt("123abc")    // 123     (a number...
isNaN("123abc")       // true     ...which is not a number)
Run Code Online (Sandbox Code Playgroud)

有了这个,我们可以看到 JavaScript 的parseInt函数返回的"123abc"是 number 123,但它的isNaN函数告诉我们这"123abc" 不是一个数字。

正确答案

ECMAScript-262isNaN第 18.2.3 节中定义了检查的工作方式。

18.2.3 isNaN(数量)

isNaN功能是%isNaN%内在的对象。当isNaN使用一个参数编号调用该函数时,将采取以下步骤:

  1. num? ToNumber(number).
  2. 如果numNaN,则返回true
  3. 否则,返回false

ToNumber它引用的函数也在ECMAScript-262 的第 7.1.3 节中定义。在这里,我们了解到 JavaScript 如何处理传入此函数的字符串。

问题中给出的第一个示例是一个仅包含空格字符的字符串。本节指出:

StringNumericLiteral那是空的或仅包含空白转换成+0

因此," "示例字符串被转换为+0,这是一个数字。

同一部分还指出:

如果语法不能将 the 解释String为 的扩展StringNumericLiteral,则 的结果ToNumberNaN

没有引用该部分中包含的所有检查," x"问题中给出的示例属于上述条件,因为它不能解释为StringNumericLiteral. " x"因此转换为NaN.


Gre*_*reg 5

我认为这是因为Javascript的输入:' '转换为零,而'x'不是:

alert(' ' * 1); // 0
alert('x' * 1); // NaN
Run Code Online (Sandbox Code Playgroud)


Bri*_*ead 5

如果你想实现一个准确的 isNumber 函数,这里有一种从Javascript 实现的方法: Douglas Crockford 的The Good Parts [第 105 页]

var isNumber = function isNumber(value) {
   return typeof value === 'number' && 
   isFinite(value);
}
Run Code Online (Sandbox Code Playgroud)

  • @Xyan 在这种情况下,此函数对于执行 OP 要求执行的任务不是很有帮助,即检查数字的字符串表示... (4认同)