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

发布于 2024-07-19 19:47:22 字数 1075 浏览 8 评论 0原文

尝试在 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 为基数中没有 "8""9",因此该函数返回零。 不管你喜欢与否,这是设计使然的

有哪些解决方法?

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


更新:

第五次JavaScript 标准版本 (ECMA-262) 引入了一项突破性的功能消除这种行为的改变。 Mozilla 有一篇很好的文章

Try executing the following in 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 !!

I just learned the hard way that JavaScript thinks the leading zero indicates an octal integer, and since there is no "8" or "9" in base-8, the function returns zero. Like it or not, this is by design.

What are the workarounds?

Note: For sake of completeness, I'm about to post a solution, but it's a solution that I hate, so please post other/better answers.


Update:

The 5th Edition of the JavaScript standard (ECMA-262) introduces a breaking change that eliminates this behavior. Mozilla has a good write-up.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

分分钟 2024-07-26 19:47:23

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

只需 指定基数,或“基数”,如下所示:

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

您还可以使用 数量

Number('08'); // 8

This is a common Javascript gotcha with a simple solution:

Just specify the base, or 'radix', like so:

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

You could also use Number:

Number('08'); // 8
没有伤那来痛 2024-07-26 19:47:23

如果您知道您的值将在带符号的 32 位整数范围内,那么 ~~x 将在所有情况下执行正确的操作。

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

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

是的,这确实很黑客,但很方便......

If you know your value will be in the signed 32 bit integer range, then ~~x will do the correct thing in all scenarios.

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

If you look up binary not (~), the spec requires a "ToInt32" conversion for the argument which does the obvious conversion to an Int32 and is specified to coerce NaN values to zero.

Yes, this is incredibly hackish but is so convenient...

最后的乘客 2024-07-26 19:47:23

parseInt 文档中,使用可选的基数参数指定以 10 为基数:

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

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

From the parseInt documentation, use the optional radix argument to specify base-10:

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

This strikes me as pedantic, confusing, and verbose (really, an extra argument in every single parseInt?) so I'm hoping there is a Better Way.

油饼 2024-07-26 19:47:23
function parseDecimal(s) { return parseInt(s, 10); }

编辑:如果您不喜欢始终将“,10”添加到 parseInt() 调用中,则创建自己的函数来执行您真正想要的操作只是一个选项。 它的缺点是它是一个非标准函数:如果你经常使用它,对你来说会更方便,但对其他人来说可能会更混乱。

function parseDecimal(s) { return parseInt(s, 10); }

edit: making your own function, to do what you really want, is just an option if you don't like adding the ",10" all the time to the parseInt() call. It has the disadvantage of being a nonstandard function: more convenient for you if you use it a lot, but perhaps more confusing for others.

阪姬 2024-07-26 19:47:23

指定基数:

var number = parseInt(s, 10);

Specify the base:

var number = parseInt(s, 10);
神经大条 2024-07-26 19:47:23

如果没有第二个参数,将 parseInt 替换为假定十进制的版本会不会很顽皮? (注 - 未测试)

parseIntImpl = parseInt
parseInt = function(str, base){return parseIntImpl(str, base ? base : 10)}

Would it be very naughty to replace parseInt with a version that assumes decimal if it has no second parameter? (note - not tested)

parseIntImpl = parseInt
parseInt = function(str, base){return parseIntImpl(str, base ? base : 10)}
╭ゆ眷念 2024-07-26 19:47:23

您还可以使用一元运算符 (+),而不是使用 parseFloat 或 parseInt。

+"01"
// => 1

+"02"
// => 2

+"03"
// => 3

+"04"
// => 4

+"05"
// => 5

+"06"
// => 6

+"07"
// => 7

+"08"
// => 8

+"09"
// => 9

另外,

+"09.09"
// => 9.09

MDN 链接

一元加运算符位于其操作数之前并计算其操作数,但尝试将其转换为数字(如果尚未转换为数字)。 虽然一元否定 (-) 也可以转换非数字,但一元加是将某些内容转换为数字的最快且首选的方式,因为它不对数字执行任何其他操作。

You may also, instead of using parseFloat or parseInt, use the unary operator (+).

+"01"
// => 1

+"02"
// => 2

+"03"
// => 3

+"04"
// => 4

+"05"
// => 5

+"06"
// => 6

+"07"
// => 7

+"08"
// => 8

+"09"
// => 9

and for good measure

+"09.09"
// => 9.09

MDN Link

The unary plus operator precedes its operand and evaluates to its operand but attempts to convert it into a number, if it isn't already. Although unary negation (-) also can convert non-numbers, unary plus is the fastest and preferred way of converting something into a number, because it does not perform any other operations on the number.

染柒℉ 2024-07-26 19:47:23

对于十进制怎么样:

('09'-0) === 9  // true

('009'-0) === 9 // true

How about this for decimal:

('09'-0) === 9  // true

('009'-0) === 9 // true
赠佳期 2024-07-26 19:47:23

此问题无法在 latest* Chrome 或 Firefox (2019) 中重现。

测试:

console.log(parseInt('08'));

*“自 (ECMAScript 5) JavaScript < a href="https://web.archive.org/web/20181026010700/https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt#ECMAScript_5_removes_octal_interpretation" rel="nofollow noreferrer">已放弃此行为,但您应该仍然指定基数以满足旧版浏览器的要求。" 来源

This issue cannot be replicated in latest* Chrome or Firefox (2019).

Test:

console.log(parseInt('08'));

*"Since (ECMAScript 5) JavaScript has abandoned this behaviour, but you should still specify the radix to satisfy older browsers." Source

も星光 2024-07-26 19:47:23

如果您已经使用 parseInt 完成了一堆编码,并且不想在所有内容中添加“,10”,则可以重写该函数以使基数 10 成为默认值:

window._oldParseInt = window.parseInt;
window.parseInt = function(str, rad) {
    if (! rad) {
        return _oldParseInt(str, 10);
    }
    return _oldParseInt(str, rad);
};

这可能会让后来的读者感到困惑,因此制作一个 parseInt10 () 函数可能更不言自明。 就我个人而言,我更喜欢使用一个简单的函数,而不是一直添加“,10”——只会创造更多的错误机会。

If you've done a bunch of coding already with parseInt and don't want to add ",10" to everything, you can just override the function to make base 10 the default:

window._oldParseInt = window.parseInt;
window.parseInt = function(str, rad) {
    if (! rad) {
        return _oldParseInt(str, 10);
    }
    return _oldParseInt(str, rad);
};

That may confuse a later reader, so making a parseInt10() function might be more self-explanatory. Personally I prefer using a simple function than having to add ",10" all the time - just creates more opportunity for mistakes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文