我试图将来自HTML文本字段的值与整数进行比较。它按预期工作。条件是 -
x >= 1 && x <= 999;
其中x
是文本字段的值。只要值在1-999(含)之间,条件就返回true
,否则false
。问题是,来自文本字段的值是字符串类型,我将它与整数类型进行比较。这样的比较是否可以,或者我应该使用parseInt()将x
转换为整数?
因为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]。)如果找不到可解析的数字,则返回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)
- 完全像隐式转换(例如,像上面的一元+
),但在某些实现上更慢。 (不是说它很重要。)str|0
- 隐式转换,如+str
,但它也将数字转换为32位整数(如果字符串无法转换为有效数字,则将NaN
转换为0
)。因此,如果可以忽略字符串上的额外位,parseInt
或parseFloat
就可以了。 parseInt
对于指定基数非常方便。一元+
可用于确保考虑整个字符串。做出你的选择。 :-)
最后:如果你转换为数字并想知道结果是否是NaN
,你可能会想要做if (convertedValue === NaN)
。但这不起作用,因为作为Rick points out below,涉及NaN
的比较总是错误的。相反,它是if (isNaN(convertedValue))
。
MDN's docs on Comparision声明操作数在比较之前转换为通用类型(与您正在使用的运算符):
更常用的抽象比较(例如==)在进行比较之前将操作数转换为相同的类型。对于关系抽象比较(例如,<=),在比较之前首先将操作数转换为基元,然后转换为相同类型。
如果你使用严格的比较,你只需要应用parseInt()
,在比较之前不执行自动投射。
如果var是一个字符串,你应该使用parseInt
。添加=来比较datatype
值:
parseInt(x) >== 1 && parseInt(x) <== 999;