【发布时间】:2015-08-25 11:23:07
【问题描述】:
我意识到在 javascript 中,所有 101/100、“101”/100、101/“100”和“101”/“100”都会导致 1.01(在 Chrome、FF 和 IE11 上检查)。但我找不到有关此行为的文档。
因此我的问题是使用此功能是否(跨浏览器)安全,以及这样做是否是一个好习惯(或者如果变量可以是字符串,则在除法之前使用 parseInt)?
【问题讨论】:
标签: javascript
我意识到在 javascript 中,所有 101/100、“101”/100、101/“100”和“101”/“100”都会导致 1.01(在 Chrome、FF 和 IE11 上检查)。但我找不到有关此行为的文档。
因此我的问题是使用此功能是否(跨浏览器)安全,以及这样做是否是一个好习惯(或者如果变量可以是字符串,则在除法之前使用 parseInt)?
【问题讨论】:
标签: javascript
在字符串上使用/时,字符串会隐式转换为数字,然后进行除法运算。
这可能适用于所有浏览器,但最好使用parseInt 或parseFloat 或其他方法显式转换为数字。
parseInt("101", 10) / 100
或者
parseFloat("101") / 100
【讨论】:
因此我的问题是(跨浏览器)使用此功能是否安全...
这取决于您对“安全”的定义。使用除法运算符,是的,它是指定的行为:每个操作数都被转换(隐式强制)为一个数字,然后完成数字除法。
但请注意不要过于笼统地概括这一点。 /、* 和 - 没问题,但它会咬你 +,因为如果 + 的任一操作数是字符串,+ 会进行字符串连接,而不是加法。
根据您的观点,它可能“安全”也可能不“安全”的另一种方式是隐式强制:它使用浏览器的 JavaScript 引擎将字符串转换为数字的规则。一些较旧的浏览器超出了规范(过去允许这样做)并将以0 开头的数字视为八进制(以8 为底)而不是十进制。自然,最终用户输入“0123”作为数字可能意味着数字 123,而不是数字 83(八进制中的123 = 83 十进制)。 JavaScript 引擎不再允许这样做,但一些较旧的引擎可以这样做。
一般来说,最好显式强制或转换这些操作数。您这样做的选择:
一元 + 运算符:value = +value 将使用 JavaScript 引擎的标准规则将字符串强制转换为数字。字符串中的任何非数字(科学记数法中的e 除外)都会产生NaN 的结果。另外,+"" 是 0,这可能不直观。
Number 函数:value = Number(value)。与+ 做同样的事情。
parseInt 函数,通常带有基数(数字基数):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 也可以用于类型转换,使用它们有什么缺点
*1 或/1 是依靠JavaScript 引擎来优化实际运算并进行强制运算。我不完全确定它甚至可以做到这一点(IEEE-754 数学的变幻莫测)。当然,在 99.999% 的情况下,性能并不重要,现代系统会将浮点数卸载到芯片上。但是 + 成语在 JavaScript 文化中根深蒂固,没有这个问题,所以......(你经常看到的另一个是 value = value|0。)
类型强制在这里起作用。引用@Barmar 的回答来自What exactly is Type Coercion in Javascript?
类型强制意味着当一个运算符的操作数是不同类型时,其中一个将被转换为另一个操作数类型的“等价”值。
你观察的理由也适用于其他操作-
1 + "2" will give you "12"
1 - "2" will give you -1
(因为“-”对字符串的操作不像除法那样定义“)
在“101/100”的情况下,操作“/”将决定强制转换,因为没有使用该操作符“/”对字符串定义任何操作,但存在“数字”。
只要您清楚类型强制将如何在您的操作中发挥作用,使用它是安全的(至少在现代浏览器中)。
【讨论】: