我遇到了一些代码,它们填充了这样的对象数组:
const getObj = () => {
return {a: 1, b: 2, c: 3};
}
const arr = Array(3).fill(null).map(getObj);
console.log(arr);
但是,我想知道fill(null).map(getObj)
的主要目的是什么?看起来很多余,因为我可以简单地编写以下代码并获得相同的结果数组:
const getObj = () => {
return {a: 1, b: 2, c: 3};
}
const arr = Array(3).fill(getObj());
console.log(arr);
所以,我想知道这两行代码是否做完全相同的事情,或者我缺少什么?
结果数组(fill + map
底部数组的顶部数组优先方法仅使用map
):
答案 0 :(得分:6)
Array(3).fill(getObj())
将使用对同一对象的引用填充您的数组,Array(3).fill(null).map(getObj)
将为每个元素创建对象。请参见下面的示例:
const getObj = () => {
return {a: 1, b: 2, c: 3};
}
const arr = Array(3).fill(null).map(getObj);
arr[0].b=4;
console.log(JSON.stringify(arr));
const arr1 = Array(3).fill(getObj());
arr1[0].b=4;
console.log(JSON.stringify(arr1))
答案 1 :(得分:1)
关于Array.fill,文档中指出:
当填充传递给对象时,它将复制引用并填充 对该对象的引用的数组。
因此,对对象使用Array.fill
的应用会受到一定的限制,除非您确实希望有多个对象指向相同的引用。但是,在不多的用例中,如果不理解,将导致bugs
。
对于第二种情况,当您执行Array(3).fill(null).map(getObj)
时,这是根据给定的任意大小创建新数组并同时用新对象填充它的一种方法。
fill(null)
的真正需求是由于调用Array(3)
只会做一件事。创建一个新数组并将其length
属性设置为3。就是这样!
let arr = Array(3) // returns new array with its "length" property set to 3
console.log(arr) // [empty × 3] <-- browser console
因此该数组现在仅具有长度和一堆empty
元素。在它真正具有值之前,您不能做太多事情。因此,需要fill
,以便您给它任何值,然后map
通过它来设置您实际想要的值。使用Array.map
并调用每个迭代函数可以确保您没有相同的引用。您本可以跳过fill
步骤并执行以下操作:
const getObj = () => ({a: 1, b: 2, c: 3})
// using array destructuring
let arr = [...Array(3)].map(getObj)
arr[0].a = 3
console.log(arr)
// using Array.from
let arr2 = Array.from(Array(3)).map(getObj)
arr2[0].a = 3
console.log(arr2)
有些短,可以使您获得完全相同的结果,即使用对象而不是对同一对象的引用以指定的长度填充数组。
这里的窍门是,两者都将在用undefined
值定义数组之后“填充”数组,然后map
将用我们想要的值填充数组。