为什么字符串到数字比较在Javascript中有效

时间:2015-03-11 18:43:43

标签: javascript

我正在尝试将来自HTML文本字段的值与整数进行比较。它按预期工作。 条件是 -

x >= 1 && x <= 999;

其中x是文本字段的值。当值在1-999(含)之间时,条件返回true,否则false。 问题是,来自文本字段的值是字符串类型,我将其与整数类型进行比较。这样的比较是否可以,或者我应该使用parseInt()将x转换为整数?

3 个答案:

答案 0 :(得分:9)

因为JavaScript定义>=<=(以及其他几个运算符)的方式允许它们将操作数强制转换为不同的类型。它只是运营商定义的一部分。

如果是<><=>=,则可以在§11.8.5 of the specification中列出血淋淋的详细信息。短版本是:如果两个操作数都是字符串(在必要时从对象强制后),它会进行字符串比较。否则,它会将操作数强制转换为数字并进行数字比较。

因此,您可以获得有趣的结果,例如"90" > "100"(两者都是字符串,它是字符串比较),但"90" < 100(其中一个是数字,它是数字的数字)比较)。 : - )

  

是否可以像这样进行比较,还是应该使用parseInt()将x转换为整数?

这是一个意见问题。有些人认为依靠隐含的强制手段是完全可以的;其他人认为它不是。有一些客观的论点。例如,假设您依赖于隐式转换,它很好,因为您有这些数字常量,但后来您将x与您从输入字段获得的另一个值进行比较。现在您正在比较字符串,但代码看起来相同。但同样,这是一个意见问题,你应该自己做出选择。

如果您决定先明确转换为数字,parseInt可能是您想要的,也可能不是您想要的,不会执行与隐式转换相同的操作。这是选项的简要说明:

  • parseInt(str[, radix]) - 尽可能多地将字符串的开头转换为整数(整数),忽略末尾的额外字符。所以parseInt("10x")10; x被忽略。支持可选的基数(数字基数)参数,因此parseInt("15", 16)21(十六进制为15)。如果没有基数,则假设为十进制,除非字符串以0x(或0X)开头,在这种情况下,它会跳过那些并假定为十六进制。 是否会查找新的0b(二进制)或0o(新式八进制)前缀;这两个都解析为0(某些浏览器用于将以0开头的字符串视为八进制;该行为从未指定过,并且在ES5规范中[特别禁止] [2]。)返回{{1}如果没有找到可解析的数字。

  • NaN - 与parseFloat(str)类似,但是浮点数并且仅支持小数。字符串上的额外字符将被忽略,因此parseIntparseFloat("10.5x")(忽略10.5)。由于仅支持十进制,xparseFloat("0x15")(因为解析在0处结束)。如果没有找到可解析的数字,则返回x

  • 一元NaN,例如+ - (例如,隐式转换)使用浮点和JavaScript的标准数字表示法将整个字符串转换为数字(只需数字和a小数点=十进制; +str前缀=十六进制; 0x =二进制[ES2015 +]; 0b前缀=八进制[ES2015 +]; 一些实现扩展它以对待一个前导0o作为八进制,但不是严格模式)。 0+"10x",因为NaN 被忽略。 x+"10"10+"10.5"10.5+"0x15"21+"0o10" [ES2015 +] ,8+"0b101" [ES2015 +]。有一个问题:5+"",而不是0正如您所料。

  • NaN - 完全类似于隐式转换(例如,与上面的一元Number(str)一样),但在某些实现上速度较慢。 (并非它可能很重要。)

  • 按位OR为零,例如+ - 隐式转换,如str|0,但它也将数字转换为32位整数(如果字符串无法转换为+str,则转换为NaN有效号码。

因此,如果可以忽略字符串上的额外位,0parseInt就可以了。 parseFloat对于指定基数非常方便。一元parseInt对于确保考虑整个字符串非常有用。做出你的选择。 : - )

最后:如果您要转换为数字并想知道结果是否为+,您可能会想NaN。但无法工作,因为作为Rick points out below,涉及if (convertedValue === NaN)的比较总是错误的。相反,它是NaN

答案 1 :(得分:2)

MDN's docs on Comparision表示操作数在比较之前转换为公共类型(与您正在使用的运算符):

  

更常用的抽象比较(例如==)在进行比较之前将操作数转换为相同的Type。对于关系抽象比较(例如,&lt; =),在比较之前,操作数首先被转换为基元,然后转换为相同的类型。

如果你使用严格的比较,你只需要申请parseInt(),在比较之前不会执行自动投射。

答案 2 :(得分:-1)

如果var是字符串,则应使用parseInt。添加=比较datatype值:

parseInt(x) >== 1 && parseInt(x) <== 999;