展开运算符配合解构赋值是提取对象局部属性并生成浅拷贝最直观、可读性最强的方式;支持rest模式提取剩余属性、覆盖/新增字段、条件合并及数组批量处理,但仅拷贝可枚举字符串键,不处理symbol、不可枚举属性和嵌套引用。

展开运算符(...)配合解构赋值,是提取对象局部属性并生成浅拷贝最直观、可读性最强的方式。它不依赖额外工具函数,语法简洁,且天然隔离顶层修改。
提取关键字段 + 保留其余属性为新对象
用解构 + rest 模式,把想单独使用的字段明确写出,剩余属性自动聚合成一个新对象:
- 写法必须是
{ a, b, rest }形式,rest 必须在解构末尾,否则报错 -
rest是原对象中未被显式列出的自有可枚举字符串键的浅拷贝,与原对象无引用关系 - 例如:
const { id, name, metadata } = user;→metadata就是除id和name外所有属性的新对象
一边提取一边覆盖或新增字段
在构造新对象时,直接用展开运算符铺开原对象,再写入需要更新或补充的键值对,同名键自动后写覆盖前写:
- 覆盖单个字段:
const updated = { user, name: "李四" }; - 覆盖多个 + 新增:
const withStatus = { user, status: "active", updatedAt: Date.now() }; - 条件覆盖(利用逻辑表达式):
{ user, ...(isAdmin ? { role: "admin" } : {}) }
批量处理对象数组时精准控制字段
结合 map 与解构,可在遍历中统一提取、转换、过滤,同时保证每个结果项都是独立浅拷贝:
- 提取并重命名:
arr.map(({ firstName: name, lastName: surname }) => ({ name, surname })) - 剔除敏感字段:
arr.map(({ password, __v, ...rest }) => rest) - 添加计算字段:
arr.map(item => ({ ...item, fullName: `${item.firstName} ${item.lastName}` }))
注意边界:哪些不会被拷贝
这种“优雅提取”本质仍是浅拷贝,需清楚它的能力边界:
- Symbol 键和不可枚举属性会被跳过,适合做数据净化(如剥离 UI 状态 Symbol)
-
嵌套对象仍为引用,改
rest.address.zip会同步影响原对象中的address.zip - 不继承原型链,只复制
Object.keys()能枚举出的内容











