copyWithin()是原地操作,不创建新数组、不触发内存重分配,因此高性能;它自动处理源目标重叠时的拷贝方向,支持负索引和越界容错,但不改变数组长度。

copyWithin() 是原地操作,不创建新数组、不触发内存重分配,所以比 slice + splice 或多次赋值快得多。关键在于理解它怎么“安全移动”——尤其当源和目标区域重叠时,它自动按方向调整拷贝顺序,避免中间值被提前覆盖。
目标位置 target 决定复制落点,不是插入点
target 是元素要“贴上去”的起始索引,不是腾出空位的位置。比如想把后两个元素挪到开头:[1,2,3,4,5].copyWithin(0, 3) → [4,5,3,4,5]。这里 4 覆盖了 1,5 覆盖了 2,其余不变。注意数组长度没变,只是前两位被替换了。
- target 支持负数:
copyWithin(-2)等价于copyWithin(arr.length - 2) - target 超出数组长度(如
copyWithin(100))不会报错,但实际无效果 - target 小于 0 且绝对值超过长度时,会被截为 0
源区间 [start, end) 是左闭右开,end 不包含
start 和 end 定义你要“搬哪一段”,范围是 [start, end),即包含 start、不包含 end。例如 [1,2,3,4,5].copyWithin(2, 1, 3) 搬的是索引 1 和 2 的值(2,3),贴到索引 2 开始的位置 → [1,2,2,3,5]。
- 省略 end 默认复制到末尾;省略 start 默认从 0 开始
- start/end 都支持负数:-1 表示最后一个元素,-3 表示倒数第三个
- 如果 start ≥ end(比如
copyWithin(0, 3, 1)),什么也不做
重叠时自动防覆盖,但方向得你来控
当源和目标区域有交集,copyWithin 内部会判断方向:若 target < start(前移),从左往右拷;若 target > start(后移),从右往左拷。你不用手动分步,但得预判结果是否符合预期。
- 前移删头:用
arr.copyWithin(0, n)覆盖前 n 位,再配arr.length -= n真删 - 后移腾位:想在索引 2 插入,先扩容(如
arr.push(undefined)),再arr.copyWithin(3, 2, arr.length - 1) - 用负索引简化逻辑:把最后 3 个移到开头,直接
arr.copyWithin(0, -3)
注意稀疏数组和 TypedArray 的差异
普通数组允许空槽(sparse),copyWithin 会把 undefined 当真实值复制过去;TypedArray(如 Uint8Array)没有稀疏概念,未赋值位置默认是 0,复制行为一致但语义不同。
- 对稀疏数组操作后,空槽可能被填满或保留,取决于源区间是否含空槽
- TypedArray 兼容性与普通数组相同(IE11+),可放心迁移
- 所有场景下都不改变原数组 length,需要截断或扩容得额外处理


















