在JavaScript中领先零
尝试这个:
<script language="javascript"> var iTest=040; alert(iTest); </script>
从什么时候开始是40 = 32?
前导零,数字被解释为八进制和4 * 8 = 32。
因为0前缀表示八进制数(基数8)。
TL; DR
它被视为八进制数(基数为8),因为前导0 ,就像前导的0x会使其hex(基数为16)一样。 这有一个漫长而折磨的历史,不再是如何编写现代JavaScript的八进制数字。 在使用严格模式的现代JavaScript中,“传统”八进制格式是语法错误; 八进制数字是用0o前缀编写的。
历史
早期(以Netscape的初始语言以及第一和第二ECMAScript规范),数字文本中的前导0正式表示八进制 (基数为8),正如前导的0x表示hex(基数为16):
OctalIntegerLiteral :: 0 OctalDigit OctalIntegerLiteral OctalDigit
例如, 012和0xA都是写十进制数的方法。 这与其他一些与JavaScript(C,C ++,Java,…)语法相似的语言保持一致,但是这种语言非常混乱。
从ECMAScript 3开始,八进制文本的forms被降级为一个可选的扩展,并且十进制整数文字被改变了,所以它们不能有前导零(除非实现包含扩展):
DecimalIntegerLiteral :: 0 NonZeroDigit DecimalDigits(opt)
但ECMAScript 5禁止在严格模式下执行此操作:
符合的实现在处理严格模式代码(见10.1.1)时 ,不得扩展NumericLiteral的语法,使其包含如B.1.1所述的OctalIntegerLiteral 。
ECMAScript 6 (ECMAScript 2015)引入了BinaryIntegerLiteral和OctalIntegerLiteral ,所以现在我们有更多连贯的文字:
- BinaryIntegerLiteral ,前缀为
0b或0B。 - OctalIntegerLiteral ,以
0o或0O为前缀。 - HexIntegerLiteral ,前缀为
0x或0X。
旧的OctalIntegerLiteral扩展名已经改名为LegacyOutIntegerLiteral ,但仍然允许在非严格模式下使用。
结论
因此,如果你想parsing一个基数为8的数字,可以使用0o或0O前缀(旧的浏览器不支持),或者使用parseInt 。
如果你想确保你的数字将以10为基础进行parsing,请删除前导零或使用parseInt 。
例子
-
010- 在严格模式下(需要ECMAScript 5),这是一个语法错误。
- 在非严格模式下,可能是语法错误或返回
8(实现相关)。
-
0O10- 在ECMAScript 6之前,它们是语法错误。
- 在ECMAScript 6中,它们返回
8。
-
parseInt('010', 8)- 它返回
8。
- 它返回
-
parseInt('010', 10)- 它返回
10。
- 它返回
如果你有兴趣,你可以在这里find当前的生活规范,以及这里的历史版本。