展开运算符(...)是实现局部覆盖式浅拷贝最简洁手段,支持对象/数组的顶层字段覆盖、新增与条件处理,但嵌套结构仍共享引用,需逐层展开才能隔离修改。

展开运算符(...)是实现“局部覆盖式浅拷贝”的最简洁手段——它天然支持在复制原始对象/数组的同时,精准替换或新增指定字段,且不修改原数据。
一、对象的局部覆盖式浅拷贝
语法结构为 { ...originalObj, key: newValue }。展开原对象所有顶层属性,再按顺序写入新键值对;同名键会自动覆盖前面的值。
- 覆盖单个字段:
const updated = { ...user, name: "张三" }; - 覆盖多个字段:
const updated = { ...user, age: 25, city: "杭州" }; - 新增字段(原对象无该键):
const withId = { ...user, id: 1001 }; - 条件覆盖(利用逻辑表达式):
{ ...user, ...(isAdmin ? { role: "admin" } : {}) }
二、数组的局部覆盖式浅拷贝
适用于替换某索引位置的元素、插入新项、或跳过特定项,本质仍是展开 + 重组。
- 替换第2项(索引1):
const newArr = [ ...arr.slice(0, 1), "newVal", ...arr.slice(2) ]; - 在开头添加 + 末尾替换:
const newArr = [ "first", ...arr.slice(1, -1), "last" ]; - 过滤后重建(如移除某个值):
const filtered = [ ...arr.filter(item => item !== "toRemove") ];
三、注意:覆盖只作用于顶层,嵌套结构仍共享引用
局部覆盖不能改变浅拷贝的本质——嵌套对象或数组的内存地址不会被复制,仅顶层字段被重写。
- 安全操作:
const copy = { ...obj, name: "新名字" };→obj.name不变 - 危险操作:
copy.profile.age = 30;→obj.profile.age同步变化(因profile是同一引用) - 若需修改嵌套字段又不影响原对象,须连同嵌套层一起展开:
{ ...obj, profile: { ...obj.profile, age: 30 } }
四、对比其他浅拷贝方式的适用场景
展开运算符不是唯一选择,但最适合“边拷贝边定制”:
-
Object.assign():适合动态多源合并,如
Object.assign({}, defaults, overrides) - slice() / concat():数组操作更语义化,但不如展开灵活(尤其插入/条件处理)
- 展开运算符:代码最简、可读性最强、天然支持解构与条件展开,是 Vue/React 等框架中状态更新的首选写法










