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

Por*_*man 280 javascript integer octal

尝试在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 !!
Run Code Online (Sandbox Code Playgroud)

我刚刚学会了JavaScript认为前导零指示八进制整数的困难方式,并且由于没有"8""9"在base-8中,该函数返回零.无论喜欢与否,这都是设计的.

解决方法有哪些?

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


更新:

JavaScript标准的第5版(ECMA-262)引入了一个突破性的变化,消除了这种行为.Mozilla 写得很好.

Pao*_*ino 324

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

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

parseInt('08',10); // 8
Run Code Online (Sandbox Code Playgroud)

你也可以使用数字:

Number('08'); // 8
Run Code Online (Sandbox Code Playgroud)

  • *数*.辉煌. (56认同)
  • 数字需要08附近的报价.也只是被警告,数字('08 .123')将产生8.123作为其输出.如果你真的想要一个整数,不要使用Number(或模式匹配你的输入以确保只有整数). (10认同)
  • 仍然,在引号中使用'08'.08不符合ECMA-262标准,并且不保证在没有警告和/或错误和/或特定指定行为的情况下成功. (5认同)
  • 号(08); 在Firefox和IE中给我8个. (3认同)
  • 它不是ECMAscript标准的一部分.我正在测试使用Spidermonkey 1.7(= Firefox JS引擎)的JSDB,并抱怨"08不是合法的ECMA-262八进制常量" (3认同)

Kar*_*tin 43

如果你知道你的值将在有符号的32位整数范围内,那么~~x在所有场景中都会做正确的事情.

~~"08" === 8
~~"foobar" === 0
~~(1.99) === 1
~~(-1.99)  === -1
Run Code Online (Sandbox Code Playgroud)

如果查找二进制not(~),则规范需要对参数执行"ToInt32"转换,该转换会明显转换为Int32,并指定将NaN值强制为零.

是的,这是令人难以置信的hackish但是很方便......

  • @SebastianGodelet,| 0. (3认同)
  • 为什么两个操作当一个二进制或足够? (2认同)

Por*_*man 24

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

parseInt('08', 10); //equals 8
parseInt('09', 10); //equals 9
Run Code Online (Sandbox Code Playgroud)

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

  • 如果你不喜欢详细程度,那么只需创建自己的函数来调用内置函数并填充你始终保持不变的参数. (6认同)
  • 实际上包装`parseInt`以便在函数表达式中使用非常重要,比如``"7","4","09","5"中的`map`.map(parseInt);``map`将传递数组中元素的*index*作为第二个参数,除非你将其包装,否则它将被`parseInt`解释为基数. (4认同)
  • Riiiiiiight,因为它不像StackOverflow上的每个人都会因为编写函数parseIntB10而责备你.为此目的编写自己的包装函数是一个糟糕的主意. (3认同)
  • @iftrue:我想你错过了我的观点.我个人并不介意只是在每个地方做parseInt(someString,10)以确保我强制基数10. OP似乎不喜欢这种方法,所以我提出了一个替代方案,我不会亲自使用但也许它符合他的需要.(这显然是JQuery背后的想法:通过增加额外的复杂性使它变得方便.我不使用JQuery,但许多人发现它很有用.) (2认同)

Jas*_*n S 11

function parseDecimal(s) { return parseInt(s, 10); }
Run Code Online (Sandbox Code Playgroud)

编辑:制作自己的功能,做你真正想要的,如果你不喜欢一直在parseInt()调用中添加",10",这只是一个选项.它具有非标准功能的缺点:如果你经常使用它会更方便,但也许会让其他人感到困惑.


Ric*_*dle 10

指定基数:

var number = parseInt(s, 10);
Run Code Online (Sandbox Code Playgroud)

  • 也许是因为它主要不是一个字符串 - >数字转换函数,而是一个从基数b数字字符串中读取数字的函数. (2认同)
  • 它默认为10,但是前导零是表示八进制的一种普遍方式. (2认同)

And*_*ffy 7

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

parseIntImpl = parseInt
parseInt = function(str, base){return parseIntImpl(str, base ? base : 10)}
Run Code Online (Sandbox Code Playgroud)

  • 这是事实,但并没有那么多.它也不是标准行为 - 八进制支持是可选的. (4认同)
  • 是的,这将是顽皮的 - 它会破坏依赖于标准行为的其他代码. (2认同)
  • 但是你也放弃了不是可选的十六进制支持,是吗?这应该总是正确的:`parseInt("0xFFFFFF")=== 16777215`,但是你的顽皮黑客已经不再适用了`parseInt("0xFFFFFF")=== 0` (2认同)
  • @ jes5199然后[ECMAScript 5决定打破依赖于该行为的其他代码](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt#Octal_interpretations_with_no_radix) (2认同)

SoE*_*zPz 6

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

+"01"
// => 1

+"02"
// => 2

+"03"
// => 3

+"04"
// => 4

+"05"
// => 5

+"06"
// => 6

+"07"
// => 7

+"08"
// => 8

+"09"
// => 9
Run Code Online (Sandbox Code Playgroud)

并有很好的措施

+"09.09"
// => 9.09
Run Code Online (Sandbox Code Playgroud)

MDN连结

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


小智 5

十进制如何:

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

('009'-0) === 9 // true
Run Code Online (Sandbox Code Playgroud)