我如何解决 JavaScript 的 parseInt 八进制行为?

IT技术 javascript integer octal
2021-02-04 02:42:22

尝试在 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 认为前导零表示八进制整数的艰难方法,并且由于没有"8"or"9"在 base-8 中,该函数返回零。不管喜欢与否,这是设计使然

有哪些解决方法?

注意:为了完整起见,我将发布一个解决方案,但这是我讨厌的解决方案,所以请发布其他/更好的答案。


更新:

JavaScript 标准的第 5 版 ( ECMA-262 ) 引入了一项重大更改,消除了这种行为。Mozilla 有一篇很好的文章

6个回答

这是一个常见的 Javascript 问题,有一个简单的解决方案:

只需指定 base或 'radix',如下所示:

parseInt('08',10); // 8

您还可以使用Number

Number('08'); // 8
Number 在 08 周围需要引号。另外请注意,Number('08.123') 将产生 8.123 作为其输出。如果你真的想要一个整数,不要使用 Number (或模式匹配你的输入以确保只有整数)。
2021-03-13 02:42:22
不过,在引号中使用 '08'。08 不符合 ECMA-262 标准,并且不能保证在没有警告和/或错误和/或特定指定行为的情况下成功。
2021-03-15 02:42:22
号码(08); 在 Firefox 和 IE 中给我 8。
2021-03-23 02:42:22
它不是 ECMAscript 标准的一部分。我正在使用 Spidermonkey 1.7(=Firefox JS 引擎)的 JSDB 进行测试,并抱怨“08 不是合法的 ECMA-262 八进制常量”
2021-03-25 02:42:22
老问题,但请注意 Number 与 parseInt 不同:stackoverflow.com/a/4090577
2021-03-31 02:42:22

如果您知道您的值将在有符号的 32 位整数范围内,那么~~x在所有情况下都会做正确的事情。

~~"08" === 8
~~"foobar" === 0
~~(1.99) === 1
~~(-1.99)  === -1

如果您查找 binary not ( ~),则规范需要对参数进行“ToInt32”转换,该参数明显转换为 Int32,并指定将NaN强制为零。

是的,这非常骇人听闻,但非常方便......

@Oleg,为什么一个就足够了?
2021-03-24 02:42:22
整个问题是关于将字符串转换为整数的 parseInt 替代方案。因此:总是。
2021-04-03 02:42:22
@Grodriguez,当 |0 中的 0 是字符串时?
2021-04-04 02:42:22
当一个二进制或就足够了时,为什么要进行两次操作?
2021-04-06 02:42:22

parseInt 文档中,使用可选的 radix 参数来指定 base-10:

parseInt('08', 10); //equals 8
parseInt('09', 10); //equals 9

这让我觉得迂腐、混乱和冗长(真的,每个 parseInt 中都有一个额外的参数?)所以我希望有更好的方法。

实际上,parseInt为了方便在函数表达式中使用,包装非常重要,例如mapin["7","4","09","5"].map(parseInt); Map会将数组中元素索引作为第二个参数传递,parseInt除非您包装它,否则它将被解释为基数。
2021-03-10 02:42:22
好吧,因为并不是 StackOverflow 上的每个人都会因为你编写函数 parseIntB10 而斥责你。为此,编写自己的包装器函数是一个糟糕的主意。
2021-03-17 02:42:22
如果您不喜欢冗长,那么只需创建自己的函数来调用内置函数并填写您始终保持不变的参数。
2021-03-29 02:42:22
@iftrue:我想你没有抓住我的意思。我个人不介意到处都做 parseInt(someString, 10) 以确保我强制以 10 为基数。 OP 似乎不喜欢这种方法,所以我提出了一个替代方案,我个人不会使用它,但也许它符合他的需要。(这显然是 JQuery 背后的想法:通过增加额外的复杂性使其方便。我不使用 JQuery,但很多人发现它很有用。)
2021-04-09 02:42:22
function parseDecimal(s) { return parseInt(s, 10); }

编辑:如果您不喜欢一直将“,10”添加到 parseInt() 调用中,那么制作您自己的函数来做您真正想做的事情只是一种选择。它有一个非标准函数的缺点:如果你经常使用它对你来说更方便,但对其他人来说可能更混乱。

指定基数:

var number = parseInt(s, 10);
哇你们好快 我什至在剪贴板上有我的答案。你是直接接入互联网,Neo-style?
2021-03-16 02:42:22
它默认为基数 10,但前导零是表示八进制的一种普遍方式。
2021-03-23 02:42:22
为什么魔鬼不是默认为基数 10
2021-03-29 02:42:22
也许是因为它主要不是作为 String->Number 转换函数,而是一个从基数 b 数字字符串读取数字的函数。
2021-04-01 02:42:22