带对象的Array.prototype.fill()传递引用而不是新实例

Koe*_*ren 41 javascript arrays

只是一个小问题.

我正在玩弄一点,并试图实例化一个新的长度x数组,其中该数组的所有元素初始化为值y

var arr = new Array(x).fill(y);
Run Code Online (Sandbox Code Playgroud)

如果y的值不是对象,则此方法很有效.意思是y是一个对象,以下是正确的:

var arr = new Array(2).fill({});
arr[0] === arr[1]; //is true;
arr[0].test = 'string';
arr[1].test === 'string'; //is also true;
Run Code Online (Sandbox Code Playgroud)

有没有办法说明在使用fill-function时应该为每个元素创建一个新对象?或者我应该将其转换为循环?

提前致谢!

Ori*_*iol 47

您可以先fill使用任何值(例如undefined)的数组,然后您将能够使用map:

var arr = new Array(2).fill().map(u => ({}));
Run Code Online (Sandbox Code Playgroud)
var arr = new Array(2).fill().map(Object);
Run Code Online (Sandbox Code Playgroud)

  • 还有`Array.from({length:2},u =>({}))` (15认同)

Kos*_*nos 19

接受的答案是好的,并且在90%的案例中都有效.

但是如果你正在制作高性能的JS应用程序,并且如果使用大/大数组,则Array.map(..)会在内存和处理器使用方面产生大的重载,因为它会创建一个数组副本.

我建议使用经典的for循环:

    a = new Array(ARRAY_SIZE);
    for (var i = 0; i < ARRAY_SIZE; i++) {
        a[i] = [];
    }
Run Code Online (Sandbox Code Playgroud)

我测试了三个替代方案,得到了这个

PS.我用这个小提琴进行测试.

  • 这不是一个公平且有效的比较,因为您预先初始化了数组并为 for 循环创建了一个 PACKED 数组。您的基准测试将重复的对象初始化时间与预初始化的本机数组迭代进行比较。去掉数组的预填充,或者将元素类型更改为非同质的,这个基准测试就会崩溃。 (4认同)
  • @user120242 我不明白你的评论?这个问题的意思是:如何用值初始化数组?我只是与接受的答案进行了比较,发现了更快的方法。如果您对数组初始化有更好的建议,请填写与我们分享:) (2认同)

Ili*_*rim 9

一个高性能解决方案: Array.from({ length: 5 }, () => new Object())

  • @morphles 如果你想初始化对象,它应该是 `_=&gt;({})` 。否则,您只需用“未定义”填充数组即可。 (3认同)
  • 我刚刚将这种初始化方式添加到上面的答案中,显然,就性能而言,这是最糟糕的方式。在我的测试中,与常规 **for 循环** 相比,这种方式显示**慢 30 倍**结果 (2认同)

Ric*_*ick 5

最短的可能:

let node =  [...Array(2)].map(_=>({}))
console.log(node)
Run Code Online (Sandbox Code Playgroud)