展开运算符(...)是es6起最直观常用的浅拷贝工具,支持数组/对象一键复制与灵活定制,但仅作浅拷贝,嵌套结构仍共享引用。

展开运算符(...)是 ES6 起最直观、最常用的浅拷贝工具,写法简洁、语义清晰,适合日常开发中快速复制数组或对象,同时支持边拷贝边定制。
数组浅拷贝:一行搞定,安全又灵活
用 [...arr] 可立即创建一个新数组,内容与原数组一致,但引用不同。原数组的修改不会影响副本,反之亦然。
- 基础复制:
const newArr = [...oldArr]; - 开头插入元素:
const withStart = [0, ...oldArr]; - 末尾追加元素:
const withEnd = [...oldArr, 99]; - 替换某位置(如索引 2):
const updated = [...oldArr.slice(0, 2), 'new', ...oldArr.slice(3)]; - 过滤后重建:
const filtered = oldArr.filter(x => x > 5).map(x => x);或直接[...oldArr.filter(x => x > 5)]
注意:若数组里含对象或嵌套数组(如 [{id:1}, [2,3]]),这些内部结构仍共享引用,修改 newArr[0].id 会影响原数组对应项。
对象浅拷贝:天然支持“覆盖式更新”
用 {...obj} 复制对象所有自身可枚举属性,生成一个新对象。它不复制原型方法、不可枚举属性或 Symbol 键。
- 纯拷贝:
const copy = {...original}; - 覆盖单字段:
const updated = {...original, name: "李四"};(同名 key 后者生效) - 新增字段:
const withId = {...original, id: 1001}; - 条件赋值:
{...original, ...(isAdmin ? {role: "admin"} : {})} - 多源合并(类似 Object.assign):
{...defaults, ...overrides}
同样要注意:嵌套对象(如 user.profile)只是引用被复制,不是深拷贝。若需改嵌套字段又不污染原数据,得手动展开下一层:{...original, profile: {...original.profile, age: 30}}。
批量处理对象数组:map + 展开组合技
对一组对象做统一浅拷贝并微调,推荐 arr.map(item => ({...item}))。
- 基础批量拷贝:
const copies = users.map(u => ({...u})); - 拷贝+重命名字段:
users.map(({name: fullName, email}) => ({fullName, email})) - 拷贝+添加时间戳:
users.map(u => ({...u, createdAt: Date.now()})) - 拷贝+过滤字段(如剔除敏感字段):
users.map(({password, __v, ...rest}) => rest)
该方式返回全新数组,每个对象也是独立引用——适合 React/Vue 中状态更新,避免直接 mutate 原始数据。
与其他浅拷贝方式对比
展开运算符不是唯一选择,但胜在可读性与表达力:
-
Object.assign({}, obj)功能等价,但语法略冗长,动态合并多对象时更灵活 -
arr.slice()或arr.concat()专用于数组,语义明确,但插入/条件操作不如展开直观 - JSON 方法(
JSON.parse(JSON.stringify()))是深拷贝,但会丢函数、undefined、Date 等,慎用
展开运算符在现代框架和工程实践中已成为首选,尤其适合状态派生、props 透传、表单初始化等场景。










