ES6+ fill()

1. 前言

在定义一个数组时,需要给数组设置默认值进行填充,ES6 提供了 fill 方法,类似 copyWithin 都是替换数组中的值,fill 可以替换一个指定的值,copyWithin 则是复制数组中的值去替换指定位置的值,不能指定值。

2. 方法详情

2.1 基本语法

fill 接收一个指定的值,替换数组中的指定位置的值,可以用于初始化默认值的数组。

语法使用:

arr.fill(value[, start[, end]])

参数解释:

参数 描述
value 用来填充数组元素的值
start (可选)起始的索引,默认值是从 0 开始的,如是负值时则是从结尾开始计算
end (可选)结束的索引,默认是数组的长度 this.length,如是负值时则是从结尾开始计算

2.2 初始化一个默认值的数组

快速初始化一个数组,并填充一个值。

let arr = Array(5).fill(1)
console.log(arr)    // [1, 1, 1, 1, 1]

Array(5) 会创建一个长度为 5 的空数组,然后使用 fill 对每一项填充一个默认值是 1。

2.3 两个参数时

有两个参数时,会从第二个参数的指定位置进行填充。如果是负值时,则从数组的最后一项往前数第几个位置开始算起。如下示例:

[1, 2, 3].fill(0, 0);      // [0, 0, 0]
[1, 2, 3].fill(0, 1);      // [1, 0, 0]
[1, 2, 3].fill(0, -1);     // [1, 2, 0]
[1, 2, 3].fill(0, -3);     // [0, 0, 0]

上面的代码中,第一个值是要填充的目标元素,第二个参数是起始位置开始替换。当第二个参数是负值时,第 3 行中第二个参数是 -1 则从数组最后一个元素开始往前计算替换的长度,这里是的长度是 1,所以数组的最后一项被替换了。第 4 行中第二个参数是 -3 可以知道和数组的长度是一样的,所以整个数组都被替换了。

2.3 三个参数时

有三个参数时,第三个参数是替换结束的位置,不包括结束的位置。

['a', 'b', 'c'].fill(4, 1, 2);    // ["a", 4, "c"]
['a', 'b', 'c'].fill(4, -3, -2);  // [4, "b", "c"]
['a', 'b', 'c'].fill(4, -3, 1);   // [4, "b", "c"]
['a', 'b', 'c'].fill(4, -2, 1);   // ["a", "b", "c"]

上面的代码中,通过上面的示例我们可以总结一点就是,找到起始位置的元素和结束位置的元素,如果它们中间有值则把中间的值替换,起始位置的索引必须小于结束位置的索引,如果没有则不会被替换。如:

  • 第 2 行中 -3 的位置是 “a”,-2 的位置是 “b”,在数组中 “a” 和 “b” 直接没有值,但是包含起始的 “a” 所以 “a” 会被替换。

  • 第 4 行中第二个参数 -2 位置元素是 “b” 索引是 1,第三个参数 1 位置的元素是 “a” 索引是 0,起始位置的索引大于结束位置的索引,所以数组中没有符合替换的元素。

3. 填充对象问题

值得注意的是,当使用 fill 对数组中的想填充的是对象时,对象是引用类型,更改其中一项其他项的值也会跟着改变,看以下示例:

var arr = Array(3).fill({})  // [{}, {}, {}]
arr[1].name = 'imooc';       // [{name: 'imooc'}, {name: 'imooc'}, {name: 'imooc'}] 

上面的代码中,初始化一个默认值是一个空对象的数组,然后给数组中的其中一个元素添加属性,其他值也会跟着改变。

4. 小结

fill 方法在初始化数组时非常实用可以快速地初始化一个带默认值的数组,另外需要注意的是如果填充的是对象时,由于对象是引用类型的方式存储的,所以改变其中一项中的值时其他项也会跟着改变。