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

问题描述 投票:2回答:3

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

x >= 1 && x <= 999;

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

javascript
3个回答
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)2115,十六进制)。如果没有基数,则假设为十进制,除非字符串以0x(或0X)开头,在这种情况下,它会跳过那些并假定为十六进制。不寻找新的0b(二进制)或0o(新式八进制)前缀;这两个都解析为0。 (有些浏览器用来处理以0开头的字符串作为八进制;从未指定过该行为,并且在ES5规范中[特别禁止] [2]。)如果找不到可解析的数字,则返回NaN
  • parseFloat(str) - 与parseInt一样,但是浮点数并且仅支持十进制。字符串上的额外字符将被忽略,因此parseFloat("10.5x")10.5(忽略x)。由于只支持十进制,parseFloat("0x15")0(因为解析在x结束)。如果找不到可解析的数字,则返回NaN
  • 一元+,例如+str - (例如,隐式转换)使用浮点和JavaScript的标准数字表示法将整个字符串转换为数字(仅数字和小数点=十进制; 0x prefix = hex; 0b = binary [ES2015 +]; 0o prefix = octal [ ES2015 +];一些实现扩展它以将领先的0视为八进制,但不是严格模式)。 +"10x"NaN因为x不被忽视。 +"10"10+"10.5"10.5+"0x15"21+"0o10"8 [ES2015 +],+"0b101"5 [ES2015 +]。有一个问题:+""0,而不是你可能期望的NaN
  • Number(str) - 完全像隐式转换(例如,像上面的一元+),但在某些实现上更慢。 (不是说它很重要。)
  • 按位OR为零,例如str|0 - 隐式转换,如+str,但它也将数字转换为32位整数(如果字符串无法转换为有效数字,则将NaN转换为0)。

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

最后:如果你转换为数字并想知道结果是否是NaN,你可能会想要做if (convertedValue === NaN)。但这不起作用,因为作为Rick points out below,涉及NaN的比较总是错误的。相反,它是if (isNaN(convertedValue))


2
投票

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

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

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


-1
投票

如果var是一个字符串,你应该使用parseInt。添加=来比较datatype值:

parseInt(x) >== 1 && parseInt(x) <== 999;
© www.soinside.com 2019 - 2024. All rights reserved.