让NaN不一致地映射parseInt

Unk*_*wns 19 javascript arrays nan

正在玩一些代码来创建一个数组,0并发现只NaN返回一个值而不是0.我在Chrome,Node和Firefox中得到了它.

导致第二个价值的原因是NaN什么?

var arr = new Array(32).join(0).split('').map(parseInt)
// prints [0, NaN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
console.dir(arr)
Run Code Online (Sandbox Code Playgroud)

Ori*_*iol 26

那是因为传递给的函数map将使用三个参数调用:

  1. 当前数组项
  2. 该项目的索引
  3. 整个阵列

在这种情况下,该函数parseInt只使用两个参数:

  1. 要解析的字符串
  2. 用于解析字符串的基数
  3. 其他参数将被忽略.

因此,对于数组中的第二项(即索引1),调用将是

parseInt("0", 1, ignoredArray)
Run Code Online (Sandbox Code Playgroud)

当基数为时1,NaN返回:

  • R = ToInt32(基数).
  • 如果R ≠0,那么
    • 如果R <2或R > 36,则返回NaN.

另请注意,如果你使用更大的数字new Array(99),你会看到NaN从索引37开始.


Poi*_*nty 9

.map()函数将三个参数传递给回调,其中两个用于parseInt():值和索引(第三个是数组本身).当索引为时1,任何数字字符串都将是无效值.该parseInt()函数忽略了第二个参数0.

详细说明:对于第一个元素,parseInt()就像这样调用:

parseInt("0", 0)
Run Code Online (Sandbox Code Playgroud)

因为数组值为零且索引为零.在第二个电话,它是这样的:

parseInt("0", 1)
Run Code Online (Sandbox Code Playgroud)

并返回NaN.

请注意,如果您对结果都不是太整杂,那么您可以使用Number构造函数执行以下操作:

var arr = new Array(32).join(0).split('').map(Number);
Run Code Online (Sandbox Code Playgroud)

在ES2015中(最新批准的JavaScript标准,如果我们都非常好,将在所有浏览器中完全实现,如圣诞礼物),您可以使用以下.fill()功能:

var arr = new Array(31).fill(0);
Run Code Online (Sandbox Code Playgroud)

  • [**三个**参数](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map),第三个是你要映射的数组.`parseInt`忽略了第三个. (6认同)

pax*_*blo 6

映射将三个参数传递给它的函数:

  • 元素;
  • 数组中该元素的索引; 和
  • 数组本身.

parseInt函数将查看前两个函数,将第一个正确地视为字符串,但将第二个视为要使用的基础.当基数既不为零也不在包含范围内时2..36,它返回NaN (1).如果你有一个包含四十个元素的数组,你最后也会看到一堆NaN值:

0, NaN, 0, 0, 0, ... 0, 0, 0, NaN, NaN
Run Code Online (Sandbox Code Playgroud)

如果数字字符串不是零,你也会得到一些非常奇怪的结果,因为数组索引会决定用什么基数来解释它.

要真正解决这个问题,你可以提供一个函数来翻译map parseInt 期望的东西(一个地图,我想你可以调用它):

function myParseInt(s,r,a) { return parseInt(s,10); }
var arr = new Array(32).join(0).split('').map(myParseInt)
alert(arr)
Run Code Online (Sandbox Code Playgroud)

您可能还想看一下创建此数组的方式,它实际上最终会变成一个大小为31而不是32的数组.如果您只想要一个'0'字符数组,您可以使用:

var arr = new Array(32).fill('0')
Run Code Online (Sandbox Code Playgroud)

假设您有一个支持ECMAScript 2015的浏览器,截至本答复时,它是Safari,Firefox和Chrome桌面.


(1)基数为零是处理十六进制前缀等内容的默认情况.

一个基数在纯粹的位置系统中是没有意义的(其中每个数字乘以基数的幂并累加),因为唯一允许的数字将是0,因此每个地方值将是零乘以.换句话说,基础系统中唯一可能的数字将为零.1n

从基地236,因此也更加理性.