Array.prototype.copyWithin()是JavaScript中唯一原地移动元素且不创建新数组的内置方法,通过类似memmove的内部拷贝实现O(k)时间复杂度的片段平移,支持重叠区间、负索引及target/start/end三参数控制,适用于缓冲区、滑动窗口和队列模拟等高频更新场景。

Array.prototype.copyWithin() 是 JavaScript 中唯一能在原数组上直接移动元素、不创建新数组也不触发内存分配的内置方法。它通过内部内存拷贝(类似 C 的 memmove)实现 O(k) 时间复杂度的片段平移,特别适合高频更新的缓冲区、滑动窗口或队列模拟场景。
理解 copyWithin 的三参数语义
调用形式为 arr.copyWithin(target, start, end),三个参数均为索引(支持负数):
- target:目标起始位置(元素将被复制到此处及之后)
- start:源片段起始索引(含)
-
end:源片段结束索引(不含),默认为
arr.length
关键特性:即使 target 与源区间重叠,方法也能正确处理(类似 memmove 而非 memcpy),因此可安全用于左移、右移、旋转等操作。
实现数组左移(向头部压缩)
例如将索引 3~6 的元素左移 2 位,腾出末尾空间:
const arr = [0, 1, 2, 3, 4, 5, 6, 7];<br>arr.copyWithin(3, 5, 7); // 把 [5,6] 复制到位置 3 开始<br>// → [0, 1, 2, 5, 6, 5, 6, 7]
注意:这仅移动数据,未清除“残留”——若需逻辑上丢弃原位置元素,需手动填充(如用 fill(undefined, start, end))。
实现数组右移(为新数据预留头部)
例如为插入 2 个新元素腾出前两个位置,将原 [0,1,…,5] 右移:
const arr = [0, 1, 2, 3, 4, 5];<br>arr.copyWithin(2, 0, 4); // 把 [0,1,2,3] 复制到位置 2 开始<br>// → [0, 1, 0, 1, 2, 3]<br>// 此时索引 0~1 空闲,可写入新值
技巧:右移时确保 target ,避免覆盖未读取的源数据;左移则相反(<code>target > start)。
结合 fill 实现“逻辑删除 + 平移”闭环
真实场景中,平移常伴随旧数据失效。例如 FIFO 队列出队后清理头部:
function shiftN(arr, n = 1) {<br> if (n <= 0 || n >= arr.length) return;<br> arr.copyWithin(0, n); // 整体左移 n 位<br> arr.fill(undefined, arr.length - n); // 清理末尾 n 个“脏”位置<br>}<br><br>const queue = ['a', 'b', 'c', 'd'];<br>shiftN(queue, 2); // → ['c', 'd', undefined, undefined]该模式零内存分配、无循环遍历,比 splice(0,n) 或 slice(n) 更高效,尤其适用于长度固定的环形缓冲区模拟。


















