[英]Can any one explain me how does the string and number comparison work in javascript?
[英]Why does string to number comparison work in Javascript
我正在尝试将来自 HTML 文本字段的值与整数进行比较。 它按预期工作。 条件是——
x >= 1 && x <= 999;
其中x
是文本字段的值。 只要值介于 1-999(含)之间,条件返回true
,否则返回false
。 问题是,来自文本字段的值是字符串类型,我将它与整数类型进行比较。 可以进行这样的比较还是应该使用 parseInt() 将x
转换为 integer ?
因为 JavaScript 定义>=
和<=
(以及其他几个运算符)的方式允许它们将其操作数强制转换为不同的类型。 它只是运算符定义的一部分。
在<
、 >
、 <=
和>=
的情况下,血淋淋的细节在规范的 §11.8.5 中列出。 简短的版本是:如果两个操作数都是字符串(在从对象中强制转换之后,如有必要),它会进行字符串比较。 否则,它将操作数强制为数字并进行数字比较。
因此,您会得到有趣的结果,例如"90" > "100"
(两者都是字符串,这是一个字符串比较)但"90" < 100
(其中一个是数字,这是一个数字比较)。 :-)
可以进行这样的比较还是应该使用 parseInt() 将 x 转换为 integer ?
这是一个见仁见智的问题。 有些人认为依靠隐含的强制是完全可以的; 其他人认为不是。 有一些客观的论据。 例如,假设您依赖隐式转换,这很好,因为您有那些数字常量,但后来您将x
与从输入字段获得的另一个值进行比较。 现在您正在比较字符串,但代码看起来相同。 但同样,这是一个见仁见智的问题,你应该做出自己的选择。
如果您确实决定首先显式转换为数字,则parseInt
可能是也可能不是您想要的,并且它不会做与隐式转换相同的事情。 以下是选项的概要:
parseInt(str[, radix])
- 尽可能多地将字符串的开头转换为一个整数(整数),忽略末尾的额外字符。 所以parseInt("10x")
是10
; x
被忽略。 支持可选的基数(数字基数)参数,因此parseInt("15", 16)
是21
(十六进制的15
)。 如果没有基数,则假定为十进制,除非字符串以0x
(或0X
)开头,在这种情况下,它会跳过这些并假定为十六进制。 不寻找新的0b
(二进制)或0o
(新式八进制)前缀; 这两个都解析为0
。 (某些浏览器过去将字符串以0
开头视为八进制;该行为从未指定,并且在 ES5 规范中[特别禁止][2]。)如果找不到可解析的数字,则返回NaN
。
Number.parseInt(str[, radix])
- 与上面的parseInt
完全相同的功能。 (从字面上看, Number.parseInt === parseInt
是true
。)
parseFloat(str)
- 与parseInt
类似,但处理浮点数且仅支持十进制。 字符串上的额外字符再次被忽略,因此parseFloat("10.5x")
为10.5
(忽略x
)。 由于仅支持十进制,因此parseFloat("0x15")
为0
(因为解析在x
处结束)。 如果没有找到可解析的数字,则返回NaN
。
Number.parseFloat(str)
- 与上面的parseFloat
完全相同的函数。
一元+
,例如+str
- (例如,隐式转换)使用浮点和 JavaScript 的标准数字表示法将整个字符串转换为数字(只有数字和小数点 = 十进制; 0x
前缀 = 十六进制; 0b
= 二进制 [ES2015+]; 0o
前缀 = 八进制 [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
对于指定基数非常方便。 一元+
对于确保考虑整个字符串很有用。 任你选择。 :-)
对于它的价值,我倾向于使用这个功能:
const parseNumber = (str) => str ? +str : NaN;
(或修剪空白的变体。)注意它如何处理+""
为0
的问题。
最后:如果您要转换为数字并想知道结果是否为NaN
,您可能会想这样做if (convertedValue === NaN)
。 但这行不通,因为正如 Rick 在下面指出的那样,涉及NaN
的比较总是错误的。 相反,它是if (isNaN(convertedValue))
。
MDN's docs on Comparision声明操作数在比较之前转换为通用类型(与您正在使用的运算符):
更常用的抽象比较(例如 ==)在进行比较之前将操作数转换为相同的类型。 对于关系抽象比较(例如,<=),操作数首先转换为基元,然后转换为相同类型,然后再进行比较。
如果您使用的是严格比较,则只需要应用parseInt()
,在比较之前不会执行自动转换。
如果 var 是字符串,则应使用parseInt
。 添加 = 来比较datatype
值:
parseInt(x) >== 1 && parseInt(x) <== 999;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.