Array.map没有'似乎无法处理未初始化的数组

Array.map doesn't seem to work on uninitialized arrays

本文关键字:处理 初始化 数组 没有 map Array      更新时间:2024-02-04

我正试图使用map函数在未初始化的数组上设置默认值,但似乎不起作用,关于如何设置默认值有什么想法吗?

考虑一下我在Chrome控制台中尝试的这个代码片段。

> var N = 10;
> var x = new Array(N);
> x
  [undefined x 10]
> x.map(function(i) { return 0;});
  [undefined x 10]

我希望数组初始化为0。

如果您想填充数组,可以使用Array(5).fill(),然后这些方法将按预期工作——请参阅aasha7中的其他相关答案。较旧的预填充方法包括:

Array.apply(null, new Array(5)).map(function() { return 0; });
// [ 0, 0, 0, 0, 0 ]

在阅读了评论中链接的一篇帖子后,我发现这也可以写成

Array.apply(null, {length: 5}).map(function() { return 0; });

但是,尝试对未定义的值使用.map是行不通的。

x = new Array(10);
x.map(function() { console.log("hello"); });
// so sad, no "hello"
// [ , , , , , , , , ,  ]

.map将跳过未定义的值:(

我只想指出,您现在可以执行以下操作:

Array(2).fill().map(_ => 4);

这将返回[4, 4]

ECMAScript语言规范就是这样描述的

以下是Array.prototype.map的相关部分,如(§15.4.4.19)所述

  • 8。重复,同时k < len
    • a) PkToString(k)
    • b) kPresent是用参数Pk调用O的[[HasProperty]]内部方法的结果
    • c) 如果kPresenttrue,则
      • 施展魔法

由于数组中没有初始化的成员,因此调用例如new Array (1337).hasOwnProperty (42)的结果为false,因此不满足步骤8.c中的条件。

然而,你可以使用一个小"黑客"做你想做的事。

Array.apply(null, { length: 5 }).map(Number.call, Number) //[0, 1, 2, 3, 4]

@Zirak 对此进行了详尽的解释

没有Array.prototype.fill:的可能解决方案

[...Array(10)].map((_, idx) => idx); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

.map()函数跳过从未赋值的条目。因此,在像您这样新构建的数组上,它基本上什么都不做。

以下是MDN的描述。

使用.map(),会跳过未定义的元素,并且不会将其传递给回调,因此,如果您的数组中没有实际包含任何内容的元素,则永远不会调用回调。

来自ECMA脚本262,5.1规范,第15.4.4.19节:

callbackfn仅对数组中实际存在它不会为数组中缺少的元素调用。

您可以使用以下函数填充一个包含零的数组:

function fillArrayWithNumber(n) {
  var arr = Array.apply(null, Array(n));
  return arr.map(function (x, i) { return 0; });
}
fillArrayWithNumber(5); // [0,0,0,0,0]

或者,只需进行一点更改,您就可以使用索引:

function fillArrayWithIndex(n) {
  var arr = Array.apply(null, Array(n));
  return arr.map(function (x, i) { return i; });
}
fillArrayWithIndex(5); // [0,1,2,3,4]

Fiddle

在先前答案的基础上,出现了新的较短语法。OP希望创建一个由N个项组成的数组,这些项用0初始化。

var N = 10;
var x = new Array(N).fill(0);
// x is now: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]

您也不需要new——在这种情况下它是可选的。

请检查目标平台的兼容性,如果不可用,请使用pollyfill。