前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库copyWithin 数组方法 高效场景
JavaScript数组与集合

copyWithin 是怎么在数组内部复制的?源和目标重叠时会覆盖错吗?

copyWithin(target, start, end) 把 [start, end) 这一段复制到从 target 开始的位置,直接修改原数组并返回它,长度不变,放不下的部分直接截掉。源和目标重叠时结果也是对的,效果等同于先把源段完整拷一份再贴过去。

前端进阶之旅 · 一题精讲更新于 2026.09.29
JavaScript#数组与集合#性能优化
先看核心答案读代码示例
理解线索

`copyWithin` 的三个参数

  1. target粘贴的起始位置,超出长度就什么都不做
  2. start源区间起点,包含,默认 0
  3. end源区间终点,不包含,默认 length,复制数量还受末尾剩余空间限制

源区间里有空位时,对应的目标位置会被删成空位,而不是写入 undefined。

核心回答

先记住这个答案

copyWithin(target, start, end) 把当前数组 [start, end) 范围的元素复制到从 target 开始的位置,覆盖那里原来的值。它直接修改原数组并返回同一个数组,长度不会变,复制到末尾放不下的部分会被截掉。参数都支持负数,含义是从末尾往前数。源和目标重叠时不会出现「刚写进去的值又被当成源」的错误,结果等同于先把源区间完整拷一份再贴到目标位置。它复制的是值或引用,源位置的元素不会被删除。

  • 修改原数组并返回它本身,长度永远不变
  • 源区间左闭右开,支持负数索引
  • 重叠时不会被覆盖错,相当于先拷贝再粘贴
  • 源位置的值还在,只是目标位置被覆盖

先看几种基本用法

把 copyWithin 想成在同一张表格里「复制一段单元格,粘贴到另一处」,表格的行数不会变。

基本复制、负数索引和返回值JavaScript
const a = [1, 2, 3, 4, 5]
console.log(JSON.stringify(a.copyWithin(0, 3))) // 把 [4, 5] 贴到开头

const c = [1, 2, 3, 4, 5]
console.log(JSON.stringify(c.copyWithin(-2, 0))) // 目标是下标 3,只放得下 2 个

const d = [1, 2, 3]
console.log(d.copyWithin(0, 1) === d, d.length) // 返回原数组,长度不变
查看输出与解释
[4,5,3,4,5]
[1,2,3,1,2]
true 3

第二个例子里,源区间是整个数组,一共 5 个元素,但目标从下标 3 开始,后面只剩 2 个位置,所以只复制了 1 和 2,其余被截掉。实际复制的数量是「源区间长度」和「目标到末尾的空间」两者中较小的那个。 第三个例子说明它是原地修改。d.copyWithin(0, 1) 返回的就是 d 本身,d 已经变成了 [2, 3, 3]。如果不想动原数组,要先复制一份再调用。

重叠时为什么不会覆盖错

当目标位置落在源区间内部、而且在源起点后面时,从前往后逐个赋值就会出错:前面刚写进去的值,会在后面被当成源再复制一次。

手写正向循环和 copyWithin 对比JavaScript
function naiveCopy(arr, target, start, end) {
  for (let i = start; i < end; i++) arr[target + (i - start)] = arr[i]
  return arr
}

console.log(JSON.stringify(naiveCopy([1, 2, 3, 4, 5], 1, 0, 3))) // 1 被一路复制下去
console.log(JSON.stringify([1, 2, 3, 4, 5].copyWithin(1, 0, 3)))
查看输出与解释
[1,1,1,1,5]
[1,1,2,3,5]

手写循环第一步把下标 1 改成了 1,第二步读下标 1 时读到的已经是新值,于是 1 被一路复制下去。copyWithin 在这种情况下会从后往前复制,先写下标 3,再写 2,最后写 1,每次读到的都还是原来的值。这和 C 语言里 memmove 处理重叠内存的思路一样。 自己实现时的规则是:目标在源起点之后且有重叠,就从后往前复制;否则从前往后。

它真正适合的场景
copyWithin 最早是为 TypedArray 设计的,普通数组也顺带有了。它适合在固定长度的缓冲区里挪数据,比如音频采样数组整体左移一段、环形缓冲区腾位置,不需要创建新数组。普通业务数组很少用到它,至于是不是比手写循环快,要看数据类型和引擎,用真实数据测过再下结论。
回答前,多想一步

容易答错的地方

以为它会返回新数组
copyWithin 和 fill、sort、reverse 一样是原地修改的。在 React 状态上直接调用它,会改掉原状态,要先 [...arr] 复制一份。
以为复制是「剪切」
源位置的元素不会被删除或清空。[1, 2, 3, 4, 5].copyWithin(0, 3) 之后,下标 3、4 上还是 4 和 5。想要移动效果,得自己再处理源位置。
以为超出长度会扩展数组
长度永远不变。target 大于等于长度时什么都不做,复制不下的部分直接丢掉,不会像给 arr[10] 赋值那样把数组撑长。
试着用自己的话回答

面试官还会怎么问?

copyWithin 复制对象时是深拷贝吗?

不是。它复制的是元素本身,对象元素复制的是引用,目标位置和源位置指向同一个对象,改一个另一个也变。

和 splice 有什么区别?

splice 可以删除和插入,会改变数组长度,后面的元素整体移动。copyWithin 只覆盖不插入,长度固定。要把一段元素挪到别处并保持其它元素顺序,用 splice;在定长缓冲区里覆盖一段,用 copyWithin。

源区间里有空位会怎样?

对应的目标位置会被删除成空位。比如 [1, , 3].copyWithin(0, 1) 的结果是下标 0 变成空位、后两项都是 3。这是因为规范在复制时先检查源属性是否存在,不存在就删除目标属性,而不是写入 undefined。

从一道题,走向一组知识

把知识连起来

数组与集合

concat 和展开运算符合并数组有什么区别?嵌套数组和空位怎么处理?

concat 总是返回新数组,copyWithin 只在原数组内部搬数据,两者对原数组的影响正好相反。

数组与集合

Array.fill 传负数的 start、end 怎么换算?为什么最后一项没被填上?

fill 往一段区间写同一个值,copyWithin 往一段区间写另一段的值,参数换算规则一样。

参考资料

  • MDN:copyWithin

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 先看几种基本用法
  3. 重叠时为什么不会覆盖错
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑