为什么字符串与数字的比较在Javascript中有效
Why does string to number comparison work in Javascript
我正在尝试将来自HTML文本字段的值与整数进行比较。它按预期工作。条件是 -
x >= 1 && x <= 999;
其中x
是文本字段的值。条件返回true
只要值介于 1-999(含)之间,否则false
。问题是,来自文本字段的值是字符串类型,我正在将其与整数类型进行比较。可以像这样进行比较还是应该使用 parseInt() 将x
转换为整数?
因为JavaScript定义>=
和<=
(以及其他几个运算符)的方式允许它们将操作数强制为不同类型的操作数。这只是运算符定义的一部分。
在<
、>
、<=
和>=
的情况下,血腥的细节在规范的§11.8.5中列出。简短的版本是:如果两个操作数都是字符串(如有必要,在从对象强制之后),它会进行字符串比较。否则,它会强制操作数为数字并进行数字比较。
因此,你会得到有趣的结果,比如"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
。 -
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)
- 与隐式转换完全相同(例如,如上面的一元+
),但在某些实现上较慢。(并不是说这可能很重要。 -
按位 OR 与零,例如
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 关于比较的文档指出,在比较(与您正在使用的运算符)之前,操作数被转换为通用类型:
如果您更常用的抽象比较(例如 ==)在进行比较之前将操作数转换为相同的类型。对于关系抽象比较(例如,<=),在比较之前,操作数首先转换为基元,然后转换为相同的类型。
使用的是严格的比较,则只需要应用parseInt()
,这在比较之前不会执行自动转换。
如果 var 是字符串,则应使用 parseInt
。添加 = 以比较datatype
值:
parseInt(x) >== 1 && parseInt(x) <== 999;
- Javascript袖珍参考,第121页:这是怎么回事;猴子补丁”;方法应该有效
- 什么'是在asp.net MVC中将本地化的resources.resx文件转换为javascript文件的有效
- Rails将JavaScript对象存储到Model的有效方式
- Javascript XMLHttpRequest——只有第一个POST请求有效
- 外部链接的Javascript文件赢得't执行,但函数有效
- 如何有效地创建多维javascript数组
- Javascript/Ajax:通过点击按钮检查有效的电子邮件和电话号码
- 如何在javascript中将字符串转换为有效日期
- javascript/jQuery:在title中添加换行符——在IE9中有效,但在IE8中无效
- 将javascript数组中的项移动到特定位置的有效方法
- Javascript:字符串中有效的基于数组的替换
- Javascript下载在firefox中停止,但在Chrome中有效
- 如何使用 JavaScript 有效地替换 HTML
- 内联javascript有效,但外部文件无效
- Javascript有效地从JSON构建表并将其添加到DOM
- 禁用提交按钮,直到表单使用javascript有效
- 使用Javascript有效地从坐标数组中获得距离最短的一对坐标
- Javascript:有效地检查文本是否为完整的HTML文档
- JavaScript有效地计算给定间隔内的平均值
- 用于自动嵌入图像 URL 的 JavaScript 有效,但出现 W3 错误