使用 ES7 中的 Array.prototype.fill() 填充数组

在前端开发中,我们经常需要创建一个由特定元素构成的数组。之前的做法是使用 for 循环,不断按照给定位置插入特定元素,在数组内填充我们想要的元素。不过,ES7 中的 Array.prototype.fill() 方法的出现为我们解决了这个问题。

什么是 Array.prototype.fill() 方法

Array.prototype.fill() 方法用于填充一个数组中,从起始索引位置到终止索引位置内的所有元素,以给定的静态值。fill() 方法改变了原来的数组,而不是新创建一个副本。这个方法可以用于任何对象,包括 ArrayBuffer 和 TypedArray 对象,但是本文将以常规的数组对象为例进行讲解。

fill() 方法定义如下:

arr.fill(value[, start[, end]])
  • value - 需要填充的静态值。
  • start - 起始索引位置,默认值是 0。
  • end - 终止索引位置,默认值是 arr.length。

使用 Array.prototype.fill() 的示例

现在我们来看一个简单的示例,使用 fill() 方法创建一个长度为 5 的数组,所有元素的值都是 1:

const arr = new Array(5).fill(1);
console.log(arr); // [1, 1, 1, 1, 1]

在这个示例中,我们使用了 new Array() 来创建了一个长度为 5 的空数组,然后使用 fill() 方法将这个数组的所有元素都填充成了 1。

接下来,我们可以尝试填充数组的一部分元素。这里我们创建了一个长度为 6 的数组,然后使用 fill() 方法来填充从索引位置 2 到索引位置 4 的所有元素为 0:

const arr = new Array(6).fill('*').fill(0, 2, 4);
console.log(arr); // ['*', '*', 0, 0, '*', '*']

在这个示例中,我们首先用 fill() 方法将数组中所有的元素填充成了 *。然后我们使用 fill() 方法的第二个和第三个参数,将数组中索引位置 2 到索引位置 4 之间的元素填充成了 0。

如果我们不指定终止索引位置,fill() 方法将从起始索引到数组的结尾一直填充,直到所有的数组元素都被填充为止。例如,让我们用 fill() 方法将数组的元素从索引位置 1 填充到数组结尾:

const arr = new Array(4).fill(1).fill(2, 1);
console.log(arr); // [1, 2, 2, 2]

在这个示例中,我们首先将数组的所有元素都填充成了 1。然后,我们使用 fill() 方法的第二个参数将数组的第二个元素(索引位置为 1)开始,一直填充到了数组结尾。

使用 Array.prototype.fill() 的注意事项

虽然 fill() 方法创建一个具有给定静态值的数组非常方便,但是开发者需要注意 fill() 方法的一个问题。如果你尝试使用 fill() 方法并理解它的底层实现,你就会发现,它使用的是引用值。这意味着,如果你使用 fill() 方法初始化一个由对象组成的数组,那么你会得到一个由同一个对象引用组成的数组。

以下是一个示例展示了这个问题:

const obj = { name: 'Alice' };
const arr = new Array(3).fill(obj);
console.log(arr); // [{ name: 'Alice' }, { name: 'Alice' }, { name: 'Alice' }]

obj.name = 'Bob';
console.log(arr); // [{ name: 'Bob' }, { name: 'Bob' }, { name: 'Bob' }]

在这个示例中,我们创建了一个对象 obj,然后使用 fill() 方法创建了一个由三个 obj 引用组成的数组。当我们更改 obj 对象的属性时,这个属性会反映在填充的数组中。

为了避免这个问题,最好在填充数组时使用复制的对象而不是直接引用。

总结

在本文中,我们介绍了 ES7 中的 Array.prototype.fill() 方法,并通过多个示例展示了这个方法的用法。使用 fill() 方法可以帮助开发者快速填充数组,避免了使用 for 循环的繁琐操作。但是,需要注意 fill() 方法使用的是引用值,对于初始化一个由对象组成的数组时必须要使用复制的对象。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65b0e0a9add4f0e0ffa395ca