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

Kev*_*dra 2 javascript

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

x >= 1 && x <= 999;
Run Code Online (Sandbox Code Playgroud)

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

T.J*_*der 13

因为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以八进制开头的字符串;从未指定过该行为,并且在ES5规范中[明确禁止] [2].)0o如果找不到可解析的数字,则返回.

  • 0- 喜欢0,但是浮点数并且只支持小数.再串上多余的字符被忽略,所以NaNNumber.parseInt(str[, radix])(将parseInt被忽略).因为只支持十进制,Number.parseInt === parseInt所以true(因为解析结束于此parseFloat(str)).parseInt如果找不到可解析的数字,则返回.

  • 一元parseFloat("10.5x"),例如10.5- (例如,隐式转换)使用浮点和JavaScript的标准数字表示法将整个字符串转换为数字(只是数字和小数点=十进制; x前缀=十六进制; parseFloat("0x15")前缀=八进制[ES2015 +]; 一些实现扩展它将前导0视为八进制,但不是严格模式).xNaN因为Number.parseFloat(str)忽略.parseFloat+,+str0x,0b0o,0+"10x"[ES2015 +].有一个问题:NaNx,不像+"10"你想象的那样.

  • 10- 完全像隐式转换(例如,像+"10.5"上面的一元),但在某些实现上更慢.(不是说它很重要.)

  • 按位或与零个,例如10.5-隐式转换,例如+"0x15",但随后又转换成一个32位的整数的数目(并且转换21+"0o10"如果字符串不能被转换为有效的数).

所以,如果可以忽略字符串上的额外位,8或者没问题+"0b101".5指定基数非常方便.一元+""可用于确保考虑整个字符串.做出你的选择.:-)

最后:如果您要转换为数字并想知道结果是否存在0,那么您可能会想要这样做NaN.但这不起作用,因为正如里克在下面指出的那样,涉及的Number(str)比较总是错误的.相反,它是+.