【问题标题】:Why is parseInt(021, 8) === 15? [duplicate]为什么 parseInt(021, 8) === 15? [复制]
【发布时间】:2019-05-01 04:31:33
【问题描述】:

在审查parseInt(string, radix) 中: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt

除了这个之外,所有13 的例子都很有意义。

根据一个示例,parseInt(015, 10) 将返回 13。假设以 0 开头的数字被视为八进制,这是有道理的,而不管基数位置中出现的10

因此,如果八进制是在问题标题中指定的: parseInt(021, 8)

那为什么不是 17(根据 Mozilla 文档和我在 jsfiddle 的测试中的 15

任何见解将不胜感激。

【问题讨论】:

  • 如果你阅读了你链接的 MDN 文档的第一行,你会发现第一个参数应该是一个字符串。
  • 当您将数字(不是字符串)写为 021 时,它是八进制表示法。因此,当引擎解析您的代码时,它会将其解析为数字 17(十进制)。当您调用 parseInt 时,17 被转换为字符串“17”,然后解码为八进制数。 17 八进制 = 15 十进制。将其更改为字符串 "021" 即可得到预期结果。
  • parseInt(021,10) === parseInt(021) === 17。问题的根源是将“8”作为基数传递。
  • parseInt(021, 8) === parseInt(017, 10) === 15。 (因为021的内部处理)
  • @RichS 不,问题的根源不是将8 作为基数传递。如果有的话,它会将021 作为数字而不是字符串传递。这就是示例的重点。

标签: javascript


【解决方案1】:

这是因为0n 在javascript 中是octal notation,就像Oxnhex notation

console.log(021 === 0x11 && 021 === 17);

所以你写的被评价为parseInt(17, 8);

然后这 17 个数字被强制转换为字符串 "17",结果是 15。

console.log(parseInt(17, 8))

请注意,所有这些都不会在严格模式下发生,其中 0n 表示法已被弃用:

(function(){
  "use strict";
  // Syntax Error
  console.log(parseInt(015, 8))
})();

【讨论】:

  • 这是对所提问题的直接回答。 parseInt 的输入可以是一个数字,虽然约定(并且强烈推荐)通常传入一个字符串。
  • 很好,你提到了严格模式
  • 你为什么说015作为八进制无效?
  • 是的,你们是对的,不知道我在想什么......
  • @RichS 在这个答案上没有人对这个函数接受什么(任何类型)以及它对它做了什么(调用 toString)有任何疑问。也许您想评论 Gerardo 的回答。 ps:不接受八进制的不是parseInt...
【解决方案2】:

parseInt 的第一个参数应该是一个字符串。同样的MDN link 说:

要解析的值。如果字符串参数不是字符串,则将其转换为字符串(使用 ToString 抽象操作)。

您可以看到这按预期工作:

console.log(parseInt("021", 8))

您的测试中的问题是您使用的是数字,而不是字符串。当您使用021 作为数字时,您已经知道(当您说“以0 开头的数字被视为八进制”)时,它会转换为"17"

console.log(021.toString())

这会给你你所看到的结果:

console.log(parseInt("17", 8))

【讨论】:

  • 根据 MDN 文档的第一行,这是正确的。
  • 我可能是在说显而易见的,但 021 是 octet 表示。因此,021 = 0*8^2 + 2*8^1 + 1*8^0 = 0 + 16 + 1 = 17。由于 0 填充,它被视为 octet 字符串。如果省略“0”,则 parseInt(21) 返回 21,而 parseInt(021) 返回 17,*即使输入已经是数字且 不是 字符串。
【解决方案3】:

当您键入021 时,这是有效的八进制数,因为前缀0 JS 将其转换为十进制17。但是,如果您键入无效的八进制数,例如019 则 JS 不会转换,而是视为十进制

console.log(021)    // octal
console.log(019)    // not octal

if( 021 < 019 ) console.log('Paradox');

【讨论】:

  • 技术上是正确的,因为9 不是八进制系统的一部分,运行时将其视为十进制
猜你喜欢
  • 1970-01-01
  • 2014-06-06
  • 1970-01-01
  • 2012-02-04
  • 2011-11-12
  • 2011-09-18
  • 2011-10-17
  • 1970-01-01
  • 2017-01-01
相关资源
最近更新 更多