在JavaScript中使用除法运算符(/)对字符串进行操作

5
我发现在JavaScript中,所有101/100、"101"/100、101/"100"和"101"/"100"的结果都是1.01(在Chrome、FF和IE11上检查)。但我找不到任何关于这种行为的文档。
因此,我的问题是是否可以安全地(跨浏览器)使用此功能,如果这样做是否是一个好习惯(或者在除法之前使用parseInt,如果变量可能是字符串)?

这是一个规范:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Data_structures - Praveen Kumar Purushothaman
3
@PraveenKumar说:“是的,有一个链接。但那不是它。”需要翻译的内容是:这个,或者更准确地说是这个PDF文件 - T.J. Crowder
3个回答

6
当您在字符串上使用/时,字符串会被隐式转换为数字,然后执行除法运算。
这在所有浏览器中可能有效,但最好的做法是使用parseIntparseFloat或其他方法明确地将其转换为数字。
parseInt("101", 10) / 100

或者

parseFloat("101") / 100

ECMAScript除法运算符规范


这是一个很好的答案,但您链接的文档中“应用/运算符”部分仍然不涉及字符串。 - Arsen
1
@Arsen:是的(这也是旧规范),http://www.ecma-international.org/ecma-262/6.0/index.html#sec-multiplicative-operators-runtime-semantics-evaluation 是讨论当前规范中隐式强制转换的部分。(但仍然是一个好答案,正如你所说;我投了赞成票。) - T.J. Crowder

5
因此,我的问题是使用这个特性(跨浏览器)是否安全... 这取决于你对“安全”的定义。使用除法运算符时是指定的行为:每个操作数都会被转换(隐式强制转换)为数字,然后进行数字除法。但要小心不要过度概括。你可以使用 /,* 和 -,但在 + 上它会让你受挫,因为如果 + 的任一操作数是字符串,则 + 将执行字符串连接而非加法。另一个可能或可能不“安全”的方式取决于你的观点是隐式强制转换:它使用浏览器的 JavaScript 引擎用于将字符串转换为数字的规则。一些旧版浏览器超越了规范(在过去允许这样做),并将以 0 开头的数字视为八进制(base 8),而不是十进制。当然,输入数字“0123”的最终用户可能意味着数字 123 而不是数字 83(八进制中的 123 = 十进制中的 83)。JavaScript 引擎现在不再允许这样做,但某些旧版引擎仍然会这样做。通常最好显式强制转换或转换这些操作数。以下是您进行此操作的选择:单目 + 运算符:value = +value 将使用 JavaScript 引擎的标准规则将字符串强制转换为数字。字符串中的任何非数字字符(科学计数法中的 e 除外)都会导致结果为 NaN。此外,+"" 等于 0,这可能不直观。Number 函数:value = Number(value)。与 + 执行的操作相同。parseInt 函数,通常带有基数(number base):value = parseInt(value, 10)。这里的缺点是 parseInt 在字符串开头找到任何数字,但忽略后面的非数字字符,因此 parseInt("100asdf", 10) 等于 100,而不是 NaN。正如其名称所示,parseInt 仅解析整数。parseFloat 函数:value = parseFloat(value)。允许分数值,并始终使用十进制(永远不是八进制或十六进制)。对于字符串末尾的垃圾,它与 parseInt 执行的操作相同,parseFloat("123.34alksdjf") 等于 123.34。
所以,请根据您的使用情况选择适合您的工具。 :-)

"10" * 1 和 "10"/1 也可以用于类型转换,使用它们有什么缺点吗? - Tushar
1
@Tushar:乘法和除法代价很高,因此使用*1/1是依赖于JavaScript引擎来优化实际操作并执行强制转换。我不完全确定它是否可以这样做(IEEE-754数学的变幻莫测)。当然,99.999%的时间性能都无关紧要,现代系统会将浮点操作卸载到芯片上。但是,在JavaScript文化中,“+”成语根深蒂固,没有这个问题,所以…(你经常看到的另一个是'value = value | 0')。 - T.J. Crowder

0

类型强制转换在这里发挥作用。引用@Barmar的答案来自JavaScript中的类型强制转换到底是什么?

类型强制转换意味着当运算符的操作数是不同类型时,其中一个将被转换为另一个操作数类型的“等效”值。

你观察到的原因也适用于其他操作 -

1 + "2" will give you "12"
1 - "2" will give you -1 

(因为字符串上的"-"操作未定义,就像除法一样")

在例子"101/100"中,操作"/"将决定强制转换,因为没有在字符串上定义该运算符的操作,但对于"数字"是有的。

只要您清楚类型强制转换在操作中的作用,使用它是安全的(至少在现代浏览器中)。


1
类型强制转换意味着当运算符的操作数是不同类型时,它会被应用。但它并不适用于 "101" / "100" = 1.01 这种情况。 - Arsen
在这种情况下,操作符“/”将决定强制转换,因为没有针对该运算符“/”定义的字符串操作。 - amulous

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接