尝试在 JavaScript 中执行以下命令:
parseInt('01'); //equals 1
parseInt('02'); //equals 2
parseInt('03'); //equals 3
parseInt('04'); //equals 4
parseInt('05'); //equals 5
parseInt('06'); //equals 6
parseInt('07'); //equals 7
parseInt('08'); //equals 0 !!
parseInt('09'); //equals 0 !!
我刚刚了解到 JavaScript 认为前导零表示 octal integer 的艰难方法,并且由于在 base-8 中没有 "8"
或 "9"
,因此该函数返回零。不管你喜不喜欢,this is by design。
有哪些解决方法?
注意:为了完整起见,我即将发布解决方案,但这是我讨厌的解决方案,因此请发布其他/更好的答案。
更新:
JavaScript 标准的第 5 版 (ECMA-262) 引入了消除此行为的重大更改。 Mozilla 有一个很好的 write-up。
10
(十进制),除非要解析的数字以 0x
为前缀,例如 0xFF
,在这种情况下基本参数默认为16. 希望有一天,这个问题将成为遥远的记忆。
+'08' === 8
怎么样?真的!也许您的真实代码确实需要 parseInt
,但上述代码不需要。
Number('08')
0
或 undefined
并且字符串的数字以 0
数字开头而不后跟 x
或 X
时,则实现可以自行决定解释数字可以是八进制或十进制。鼓励实现在这种情况下将数字解释为十进制。“(我的重点)
这是一个常见的 Javascript 问题,有一个简单的解决方案:
只需 specify the base 或“基数”,如下所示:
parseInt('08',10); // 8
您也可以使用 Number:
Number('08'); // 8
如果您知道您的值将在有符号的 32 位整数范围内,那么 ~~x
将在所有场景中执行正确的操作。
~~"08" === 8
~~"foobar" === 0
~~(1.99) === 1
~~(-1.99) === -1
如果您查找二进制而不是 (~
),则规范要求对参数进行“ToInt32”转换,该参数明显转换为 Int32,并指定将 NaN
值强制为零。
是的,这是令人难以置信的hackish,但非常方便......
在 parseInt documentation 中,使用可选的 radix 参数指定 base-10:
parseInt('08', 10); //equals 8
parseInt('09', 10); //equals 9
这让我觉得迂腐、混乱和冗长(真的,每个 parseInt 中都有一个额外的参数?)所以我希望有更好的方法。
parseInt
以方便在函数表达式中使用非常重要,例如 ["7","4","09","5"].map(parseInt);
中的 map
Map
会将数组中元素的 index 作为第二个参数传递,这除非您包装它,否则将被 parseInt
解释为基础。
function parseDecimal(s) { return parseInt(s, 10); }
编辑:如果您不喜欢一直将“,10”添加到 parseInt() 调用中,则制作自己的函数来执行您真正想要的操作只是一种选择。它有一个非标准函数的缺点:如果你经常使用它对你来说更方便,但对其他人来说可能更混乱。
指定基数:
var number = parseInt(s, 10);
如果 parseInt 没有第二个参数,那么用假定十进制的版本替换它会很淘气吗? (注意 - 未经测试)
parseIntImpl = parseInt
parseInt = function(str, base){return parseIntImpl(str, base ? base : 10)}
parseInt("0xFFFFFF") === 16777215
,但你的顽皮黑客到位它不再起作用parseInt("0xFFFFFF") === 0
您也可以使用一元运算符 (+),而不是使用 parseFloat 或 parseInt。
+"01"
// => 1
+"02"
// => 2
+"03"
// => 3
+"04"
// => 4
+"05"
// => 5
+"06"
// => 6
+"07"
// => 7
+"08"
// => 8
+"09"
// => 9
并且为了很好的衡量
+"09.09"
// => 9.09
一元加号运算符在其操作数之前并计算其操作数,但如果尚未将其转换为数字,则尝试将其转换为数字。虽然一元否定 (-) 也可以转换非数字,但一元加号是将某物转换为数字的最快和首选方法,因为它不对数字执行任何其他操作。
十进制怎么样:
('09'-0) === 9 // true
('009'-0) === 9 // true
如果您已经使用 parseInt 完成了一堆编码并且不想将“,10”添加到所有内容,则可以重写该函数以使 base 10 成为默认值:
window._oldParseInt = window.parseInt;
window.parseInt = function(str, rad) {
if (! rad) {
return _oldParseInt(str, 10);
}
return _oldParseInt(str, rad);
};
这可能会使后来的读者感到困惑,因此制作 parseInt10() 函数可能更不言自明。就我个人而言,我更喜欢使用一个简单的函数,而不是一直添加“,10”——这只会为错误创造更多机会。
此问题无法在最新的 Chrome 或 Firefox (2019) 中复制。
0
的东西都会被解析为八进制。 :)