剩余运算符(...)在对象解构中必须位于末尾且仅出现一次,用于收集未显式声明的自有可枚举属性;不继承原型属性,不包含不可枚举属性;不能解构null或undefined,需配合可选链或空值合并防护。

可以用剩余运算符(...)在对象解构时收集所有未被显式声明的属性,生成一个新对象。关键在于:剩余运算符必须是解构模式中的**最后一个元素**,且只能出现一次。
语法要求:剩余属性必须放在末尾
错误写法会报语法错误:
❌ 不合法const { a, ...rest, b } = obj;(剩余不能在中间)const { ...first, ...second } = obj;(不能多次使用)
正确写法:
✅ 合法const { a, b, ...rest } = obj;
此时 rest 是一个包含 obj 中除 a、b 外所有可枚举自身属性的新对象。
剩余对象只包含未被解构的自有可枚举属性
它不会继承原型链上的属性,也不会包含不可枚举属性(如 Object.defineProperty 设置的 enumerable: false 属性)。
例如:
const obj = {
x: 1,
y: 2,
z: 3,
toString() { return 'custom'; }
};
Object.defineProperty(obj, 'hidden', {
value: 'nope',
enumerable: false
});
const { x, ...others } = obj;
console.log(others); // { y: 2, z: 3 } —— 没有 toString 或 hidden
可与默认值、重命名、嵌套解构组合使用
剩余运算符可以和其他解构特性共存,但顺序仍需遵守“剩余在最后”原则:
- 重命名 + 剩余:
const { name: fullName, ...info } = user; - 默认值 + 剩余:
const { age = 18, ...rest } = person; - 嵌套 + 剩余:
const { profile: { city, ...profileRest }, ...userRest } = data;
注意:不能解构 null 或 undefined
对 null 或 undefined 使用带剩余的解构会直接抛出 TypeError:
const { a, ...rest } = null; → TypeError: Cannot destructure property 'a' of 'null' as it is null.
建议配合可选链或空值合并做防护:
const data = response?.user ?? {};
const { id, ...meta } = data;










