剩余运算符解构可实现对象浅拷贝与静态裁剪,通过显式列出待排除属性并用...收集其余属性;无法动态裁剪,需配合object.fromentries等方法;不处理原型属性、symbol键及null/undefined,且为浅拷贝。

用剩余运算符(...)对对象做浅拷贝并裁剪,本质是解构出不需要的属性,再用剩余语法收集其余属性。它不能直接“删除”,而是通过解构跳过目标字段,间接实现裁剪。
基本写法:解构跳过要裁剪的属性
想移除 id 和 createdAt 字段,只保留其余属性:
const original = { id: 1, name: 'Alice', age: 30, createdAt: '2023-01-01' };
const { id, createdAt, ...rest } = original;
// rest = { name: 'Alice', age: 30 }
这里 id 和 createdAt 被显式解构出来(可忽略或另作处理),...rest 自动收集所有未被解构的自有可枚举属性,完成浅拷贝+裁剪。
一次裁剪多个字段:全部列在解构左侧
要裁剪 a、b、c 三个字段,就全写出来:
- 必须显式列出所有要排除的键,否则它们会进入剩余对象
- 顺序无关,但未列出的键才会被
...收集 - 如果原始对象有嵌套对象,内部不会被递归处理——仍是浅拷贝
const obj = { a: 1, b: 2, c: 3, d: { x: 10 }, e: 'ok' };
const { a, b, c, ...trimmed } = obj;
// trimmed = { d: { x: 10 }, e: 'ok' } → d 是引用,未深拷贝
动态裁剪?剩余运算符本身不支持,需配合其他方法
剩余运算符只接受静态键名,无法直接传入变量名列表。如需根据数组动态剔除字段,得组合 Object.keys + reduce 或 Object.fromEntries:
const omit = (obj, keysToOmit) => {
const set = new Set(keysToOmit);
return Object.fromEntries(
Object.entries(obj).filter(([key]) => !set.has(key))
);
};
const data = { id: 1, name: 'Bob', role: 'admin', token: 'xxx' };
const cleaned = omit(data, ['id', 'token']); // { name: 'Bob', role: 'admin' }
注意:这仍是浅拷贝,且不是用剩余运算符实现的——这是对“动态裁剪”需求的务实补充方案。
注意事项和常见坑
-
只能处理对象自身可枚举属性:原型链上的属性、不可枚举属性(如
Object.defineProperty设置的)不会被收集 - 不处理 symbol 键:剩余运算符默认忽略 symbol 类型的键(除非显式解构 symbol)
-
不能用于 null/undefined:解构时若源为
null或undefined会报错,建议加校验 -
浅拷贝限制:嵌套对象、数组仍共享引用,修改
rest.nested.x会影响原对象
不复杂但容易忽略细节。静态裁剪用解构+剩余最简洁;动态场景就换更灵活的方法,别硬套运算符。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











