JS中剩余属性用...在解构赋值右侧收集对象自身可枚举的剩余属性,必须位于解构表达式末尾,仅包含自有可枚举属性(含Symbol),不包含原型链或不可枚举属性。

JS 中用剩余属性(Rest Properties)收集对象的其余属性,是在解构赋值时用 ... 语法把尚未被单独列出的属性“打包”成一个新对象。
基本写法:解构时放在最后
剩余属性必须是解构表达式中的最后一个元素,否则会报错。
例如:
const user = { name: 'Alice', age: 30, city: 'Beijing', job: 'Engineer' };
// 正确:...rest 放在最后
const { name, age, ...rest } = user;
console.log(name); // 'Alice'
console.log(age); // 30
console.log(rest); // { city: 'Beijing', job: 'Engineer' }
// ❌ 错误:不能放在中间或开头
// const { name, ...rest, age } = user; // SyntaxError
剩余属性只收集“自身可枚举属性”
它不会复制原型链上的属性,也不会包含不可枚举属性(如 Object.defineProperty 设置的 enumerable: false 属性)。
- 只遍历对象自身的、可枚举的(
enumerable: true)属性 - 继承的属性(比如来自
Object.prototype)会被忽略 - Symbol 类型的键也会被包含(只要它是可枚举的)
和扩展运算符(Spread)别混淆
剩余属性(... 在解构左侧)和扩展运算符(... 在右侧或函数调用中)语法一样,但作用相反:
- 剩余属性:从一个对象里“抽出”未命名的属性 → 收集到一个新对象
- 扩展运算符:把一个对象“展开” → 复制所有可枚举属性到另一个对象或参数列表中
例子对比:
const a = { x: 1, y: 2 };
const b = { z: 3, ...a }; // 扩展:b = { z: 3, x: 1, y: 2 }
const { x, ...others } = a; // 剩余:x = 1, others = { y: 2 }
实用场景:提取配置 + 透传其余选项
常见于封装函数时分离核心参数和透传配置项:
function createUser({ name, email, ...options }) {
return {
id: Date.now(),
name,
email,
...options // 把其余字段直接合并进返回对象
};
}
createUser({
name: 'Bob',
email: 'bob@example.com',
role: 'admin',
active: true
});
// → { id: ..., name: 'Bob', email: 'bob@example.com', role: 'admin', active: true }


















