fill 和 copyWithin 是 ES6 提供的原地修改数组方法,不改变长度但直接修改原数组:fill 用固定值批量覆盖指定区域,copyWithin 将数组内某段内容复制覆盖到另一段,二者均支持负索引和边界自动截断,常用于初始化、移位、滚动等场景。

fill 和 copyWithin 都是 ES6 引入的原地操作数组方法,不改变长度,但会直接修改原数组。它们看似简单,实际用对能省下不少循环代码。
fill:快速初始化或局部赋值
fill 适合用固定值批量覆盖一段区域,比如清空、重置、打标、补位。
- 初始化全零数组:
Array(5).fill(0)→[0, 0, 0, 0, 0] - 只填前三个位置:
[1, 2, 3, 4, 5].fill(9, 0, 3)→[9, 9, 9, 4, 5] - 用负索引从末尾操作:
[1, 2, 3, 4, 5].fill('x', -2)→[1, 2, 3, 'x', 'x'](等价于fill('x', 3)) - 多维数组初始化要小心引用问题:
Array(3).fill().map(() => Array(3).fill(0))才安全;Array(3).fill(Array(3).fill(0))会导致所有行指向同一子数组
copyWithin:数组内“剪切粘贴”式搬运
copyWithin 不生成新数组,而是把某段内容复制并覆盖到另一段——常用于滚动、移位、填充重复模式。
- 把开头 3 个元素复制到末尾:
[1,2,3,4,5,6].copyWithin(3, 0, 3)→[1,2,3,1,2,3] - 向前平移:把后 4 个移到前面,覆盖前 4 位:
[1,2,3,4,5,6,7,8].copyWithin(0, 4)→[5,6,7,8,5,6,7,8] - 用负索引取末尾片段:
['a','b','c','d','e'].copyWithin(0, -2)→['d','e','c','d','e'](复制倒数两个,从索引 0 开始贴) - 边界自动截断:超出数组范围的起始/结束索引会被忽略或收缩,不会报错,也不会越界写入
组合使用:一行实现常见数据处理
两个方法可链式配合,完成更精细控制。
- 先清空中间区域再填新值:
[1,2,3,4,5,6].fill(0,2,4).fill('x',0,2)→['x','x',0,0,5,6] - 模拟“右旋”效果(如轮播缓存):
const arr = [1,2,3,4,5]; arr.copyWithin(1,0,4); arr[0] = 5;→[5,1,2,3,4] - 构造重复序列:
const a = Array(12).fill(0); a.copyWithin(0, 0, 3).copyWithin(3, 0, 3).copyWithin(6, 0, 3);→ 填出[0,0,0,0,0,0,0,0,0,0,0,0]的分块结构(实际中可用fill更简洁,但展示逻辑)
避坑提醒
这两个方法都直接改原数组,且参数行为有共性也易混淆。
- 所有索引参数都支持负数,表示从末尾倒数(
-1是最后一个),内部会转成正索引计算 -
start和end都是“含头不含尾”,即[start, end)区间 - 若
start ≥ end或范围完全越界(如start > length),操作静默跳过,不报错也不改动 -
copyWithin的target是目标起始位置,不是长度;若target + (end - start) > length,只复制到数组末尾

















