简体   繁体   English

为什么字符串到数字的比较在 Javascript 中起作用

[英]Why does string to number comparison work in Javascript

I am trying to compare a value coming from a HTML text field with integers.我正在尝试将来自 HTML 文本字段的值与整数进行比较。 And it works as expected.它按预期工作。 Condition is -条件是——

x >= 1 && x <= 999;

Where x is the value of text field.其中x是文本字段的值。 Condition returns true whenever value is between 1-999 (inclusive), else false .只要值介于 1-999(含)之间,条件返回true ,否则返回false Problem is, that the value coming from the text field is of string type and I'm comparing it with integer types.问题是,来自文本字段的值是字符串类型,我将它与整数类型进行比较。 Is it okay to have this comparison like this or should I use parseInt() to convert x to integer ?可以进行这样的比较还是应该使用 parseInt() 将x转换为 integer ?

Because JavaScript defines >= and <= (and several other operators) in a way that allows them to coerce their operands to different types.因为 JavaScript 定义>=<= (以及其他几个运算符)的方式允许它们将其操作数强制转换为不同的类型。 It's just part of the definition of the operator.它只是运算符定义的一部分。

In the case of < , > , <= , and >= , the gory details are laid out in §11.8.5 of the specification .<><=>=的情况下,血淋淋的细节在规范的 §11.8.5 中列出 The short version is: If both operands are strings (after having been coerced from objects, if necessary), it does a string comparison.简短的版本是:如果两个操作数都是字符串(在从对象中强制转换之后,如有必要),它会进行字符串比较。 Otherwise, it coerces the operands to numbers and does a numeric comparison.否则,它将操作数强制为数字并进行数字比较。

Consequently, you get fun results, like that "90" > "100" (both are strings, it's a string comparison) but "90" < 100 (one of them is a number, it's a numeric comparison).因此,您会得到有趣的结果,例如"90" > "100" (两者都是字符串,这是一个字符串比较)但"90" < 100 (其中一个是数字,这是一个数字比较)。 :-) :-)

Is it okay to have this comparison like this or should I use parseInt() to convert x to integer ?可以进行这样的比较还是应该使用 parseInt() 将 x 转换为 integer ?

That's a matter of opinion.这是一个见仁见智的问题。 Some people think it's totally fine to rely on the implicit coercion;有些人认为依靠隐含的强制是完全可以的; others think it isn't.其他人认为不是。 There are some objective arguments.有一些客观的论据。 For instance, suppose you relied on implicit conversion and it was fine because you had those numeric constants, but later you were comparing x to another value you got from an input field.例如,假设您依赖隐式转换,这很好,因为您有那些数字常量,但后来您将x与从输入字段获得的另一个值进行比较。 Now you're comparing strings, but the code looks the same.现在您正在比较字符串,但代码看起来相同。 But again, it's a matter of opinion and you should make your own choice.但同样,这是一个见仁见智的问题,你应该做出自己的选择。

If you do decide to explicitly convert to numbers first, parseInt may or may not be what you want, and it doesn't do the same thing as the implicit conversion.如果您确实决定首先显式转换为数字,则parseInt可能是也可能不是您想要的,并且它不会做与隐式转换相同的事情。 Here's a rundown of options:以下是选项的概要:

  • parseInt(str[, radix]) - Converts as much of the beginning of the string as it can into a whole (integer) number, ignoring extra characters at the end . parseInt(str[, radix]) - 尽可能多地将字符串的开头转换为一个整数(整数),忽略末尾的额外字符 So parseInt("10x") is 10 ;所以parseInt("10x")10 the x is ignored. x被忽略。 Supports an optional radix (number base) argument, so parseInt("15", 16) is 21 ( 15 in hex).支持可选的基数(数字基数)参数,因此parseInt("15", 16)21 (十六进制的15 )。 If there's no radix, assumes decimal unless the string starts with 0x (or 0X ), in which case it skips those and assumes hex.如果没有基数,则假定为十进制,除非字符串以0x (或0X )开头,在这种情况下,它会跳过这些并假定为十六进制。 Does not look for the new 0b (binary) or 0o (new style octal) prefixes;寻找新的0b (二进制)或0o (新式八进制)前缀; both of those parse as 0 .这两个都解析为0 (Some browsers used to treat strings starting with 0 as octal; that behavior was never specified, and was [specifically disallowed][2] in the ES5 specification.) Returns NaN if no parseable digits are found. (某些浏览器过去将字符串以0开头视为八进制;该行为从未指定,并且在 ES5 规范中[特别禁止][2]。)如果找不到可解析的数字,则返回NaN

  • Number.parseInt(str[, radix]) - Exactly the same function as parseInt above. Number.parseInt(str[, radix]) - 与上面的parseInt完全相同的功能。 (Literally, Number.parseInt === parseInt is true .) (从字面上看, Number.parseInt === parseInttrue 。)

  • parseFloat(str) - Like parseInt , but does floating-point numbers and only supports decimal. parseFloat(str) - 与parseInt类似,但处理浮点数且仅支持十进制。 Again extra characters on the string are ignored, so parseFloat("10.5x") is 10.5 (the x is ignored).字符串上的额外字符再次被忽略,因此parseFloat("10.5x")10.5 (忽略x )。 As only decimal is supported, parseFloat("0x15") is 0 (because parsing ends at the x ).由于仅支持十进制,因此parseFloat("0x15")0 (因为解析在x处结束)。 Returns NaN if no parseable digits are found.如果没有找到可解析的数字,则返回NaN

  • Number.parseFloat(str) - Exactly the same function as parseFloat above. Number.parseFloat(str) - 与上面的parseFloat完全相同的函数。

  • Unary + , eg +str - (Eg, implicit conversion) Converts the entire string to a number using floating point and JavaScript's standard number notation (just digits and a decimal point = decimal; 0x prefix = hex; 0b = binary [ES2015+]; 0o prefix = octal [ES2015+]; some implementations extend it to treat a leading 0 as octal, but not in strict mode).一元+ ,例如+str - (例如,隐式转换)使用浮点和 JavaScript 的标准数字表示法将整个字符串转换为数字(只有数字和小数点 = 十进制; 0x前缀 = 十六进制; 0b = 二进制 [ES2015+]; 0o前缀 = 八进制 [ES2015+];一些实现将其扩展为将前导0视为八进制,但不是在严格模式下)。 +"10x" is NaN because the x is not ignored. +"10x"NaN ,因为x未被忽略。 +"10" is 10 , +"10.5" is 10.5 , +"0x15" is 21 , +"0o10" is 8 [ES2015+], +"0b101" is 5 [ES2015+]. +"10"10+"10.5"10.5+"0x15"21+"0o10"8 [ES2015+], +"0b101"5 [ES2015+]。 Has a gotcha: +"" is 0 , not NaN as you might expect.有一个陷阱: +""0 ,而不是您可能期望的NaN

  • Number(str) - Exactly like implicit conversion (eg, like the unary + above), but slower on some implementations. Number(str) - 完全像隐式转换(例如,像上面的一元+ ),但在某些实现上较慢。 (Not that it's likely to matter.) (并不是说它可能很重要。)

  • Bitwise OR with zero, eg str|0 - Implicit conversion, like +str , but then it also converts the number to a 32-bit integer (and converts NaN to 0 if the string cannot be converted to a valid number).与零按位或,例如str|0 - 隐式转换,如+str ,但它还将数字转换为 32 位整数(如果字符串无法转换为有效数字,则将NaN转换为0 )。

So if it's okay that extra bits on the string are ignored, parseInt or parseFloat are fine.因此,如果可以忽略字符串上的额外位,则parseIntparseFloat都可以。 parseInt is quite handy for specifying radix. parseInt对于指定基数非常方便。 Unary + is useful for ensuring the entire string is considered.一元+对于确保考虑整个字符串很有用。 Takes your choice.任你选择。 :-) :-)

For what it's worth, I tend to use this function:对于它的价值,我倾向于使用这个功能:

const parseNumber = (str) => str ? +str : NaN;

(Or a variant that trims whitespace.) Note how it handles the issue with +"" being 0 . (或修剪空白的变体。)注意它如何处理+""0的问题。

And finally: If you're converting to number and want to know whether the result is NaN , you might be tempted to do if (convertedValue === NaN) .最后:如果您要转换为数字并想知道结果是否为NaN ,您可能会想这样做if (convertedValue === NaN) But that won't work , because as Rick points out below , comparisons involving NaN are always false.但这行不通,因为正如 Rick 在下面指出的那样,涉及NaN的比较总是错误的。 Instead, it's if (isNaN(convertedValue)) .相反,它是if (isNaN(convertedValue))

The MDN's docs on Comparision states that the operands are converted to a common type before comparing (with the operator you're using): MDN's docs on Comparision声明操作数在比较之前转换为通用类型(与您正在使用的运算符):

The more commonly used abstract comparison (eg ==) converts the operands to the same Type before making the comparison.更常用的抽象比较(例如 ==)在进行比较之前将操作数转换为相同的类型。 For relational abstract comparisons (eg, <=), the operands are first converted to primitives, then to the same type, before comparison.对于关系抽象比较(例如,<=),操作数首先转换为基元,然后转换为相同类型,然后再进行比较。

You'd only need to apply parseInt() if you were using a strict comparision, that does not perform the auto casting before comparing.如果您使用的是严格比较,则只需要应用parseInt() ,在比较之前不会执行自动转换。

You should use parseInt if the var is a string.如果 var 是字符串,则应使用parseInt Add = to compare datatype value:添加 = 来比较datatype值:

parseInt(x) >== 1 && parseInt(x) <== 999;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 可以任何人解释我如何在javascript中进行字符串和数字比较? - Can any one explain me how does the string and number comparison work in javascript? 在JavaScript中为什么Number()函数在这里不起作用并返回一个字符串? - In JavaScript why Number() function does not work here and gives back a string? Javascript 的字符串比较在底层是如何工作的? - How does Javascript's string comparison work at the lower level? JavaScript字符串比较和数字比较一样快吗? - Is JavaScript string comparison just as fast as number comparison? 在javascript中解析数字比较字符串 - parsing a number comparison string in javascript 为什么“+”运算符可以将字符串解析为数字? - Why does the “+” operator work in parsing string to number? JavaScript 中的比较运算符如何工作? 比较字符串到字符串,字符串到数字 - How do comparison operator in JavaScript work? Comparing string to string, string to number 为什么新的Number(2)!= JavaScript中的新字符串(“2”) - Why does new Number(2) != new String(“2”) in JavaScript 为什么Number &lt;String在JavaScript中返回true? - Why does Number < String returns true in JavaScript? 为什么即使输入的数字是 Javascript 中的字符串,年龄计算器也能正常工作? - Why does age calculator work even when the input number is a string in Javascript?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM