可使用展开运算符配合解构赋值将对象剩余属性浅拷贝至新对象,语法为{a,b,...rest},rest必须位于解构末尾,仅复制自身可枚举字符串键,不处理Symbol、嵌套引用及原型链。

可以使用展开运算符(...)配合解构赋值,将对象中除已明确提取的属性外的“剩余属性”一次性聚合到一个新对象中,实现浅拷贝。
基本语法:解构 + 展开收集剩余属性
在对象解构时,用 { a, b, ...rest } 的形式,把未被单独声明的属性全部收集进 rest 对象。这个 rest 就是原始对象中“剩余属性”的聚合拷贝(浅拷贝):
const original = { name: 'Alice', age: 30, city: 'Beijing', job: 'Engineer' };
const { name, age, ...others } = original;
console.log(others); // { city: 'Beijing', job: 'Engineer' }
console.log(others === original); // false(是新对象,非引用)
注意 rest 必须是解构中的最后一个元素
Rest 属性必须出现在解构模式的末尾,否则会报错:
- ✅ 正确:
{ id, ...meta, createdAt }→ ❌ 语法错误 - ✅ 正确:
{ id, createdAt, ...meta }→ ✅ 合法 - ✅ 正确:
{ ...meta }→ ✅ 相当于完整浅拷贝(不含原型链)
结合展开运算符实现“筛选 + 聚合”式拷贝
可先解构出需保留的字段,再用 ...rest 收集其余字段;也可进一步用展开运算符将其合并到新结构中:
const user = { id: 123, name: 'Bob', email: 'bob@example.com', role: 'admin', active: true };
// 提取关键字段,其余聚合为 metadata
const { id, name, email, ...metadata } = user;
const sanitizedUser = {
id,
name,
email,
metadata // { role: 'admin', active: true }
};
// 或直接内联展开(等效)
const inlineCopy = { id, name, email, ...user }; // ❌ 重复包含所有字段(包括 id/name/email)
// ✅ 更安全的做法是只展开 rest:
const safeCopy = { id, name, email, ...metadata };
局限性:仅浅拷贝,不处理嵌套与 Symbol 键
Rest 展开只复制对象自身可枚举、字符串键的属性,且是浅拷贝:
- ❌ 不拷贝
Symbol键(即使可枚举) - ❌ 嵌套对象仍为引用(如
address: { zip: '10001' }→rest.address与原对象共享) - ❌ 不继承原型链上的属性(符合 Object.assign 行为)
- ✅ 可与
structuredClone或深拷贝库配合实现深层聚合(需额外处理)

















