JavaScript解构赋值的剩余参数(...rest)只提取对象自身的可枚举属性,不继承原型链上的任何属性,包括可枚举的原型属性、Symbol键、getter等,仅等价于Object.keys()遍历自身属性。

JavaScript 解构赋值的剩余参数(...rest)**不会继承或捕获原型上的属性**,它只提取对象自身的可枚举属性。原型链在此过程中完全不参与。
剩余参数只遍历自身属性
解构时的 { ...rest } = obj 本质是执行类似 Object.assign({}, obj) 的浅拷贝逻辑(仅自身可枚举属性),原型链被忽略:
- 即使
obj.__proto__.x = 42,{ ...rest } = obj后rest.x为undefined -
for...in会遍历原型属性,但解构剩余参数不用for...in,它用的是自有属性枚举(等价于Object.keys()) - 不可枚举属性(如
Object.prototype.toString)同样不会被收集
想包含原型属性?需手动合并
若业务确实需要把原型链上的可枚举属性也纳入剩余对象,必须显式遍历原型链并合并:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
function getOwnAndInherited(obj) {
const result = {};
for (let o = obj; o; o = Object.getPrototypeOf(o)) {
Object.getOwnPropertyNames(o).forEach(key => {
if (!result.hasOwnProperty(key) && Object.prototype.propertyIsEnumerable.call(o, key)) {
result[key] = o[key];
}
});
}
return result;
}
const parent = { a: 1 };
const child = Object.create(parent);
child.b = 2;
// 默认解构
const { ...rest1 } = child; // { b: 2 } —— a 被忽略
// 手动合并原型
const rest2 = getOwnAndInherited(child); // { a: 1, b: 2 }
注意 Symbol 属性和 getter 的行为
剩余参数对特殊属性的处理也遵循自有性原则:
立即学习“Java免费学习笔记(深入)”;
-
Symbol 键:只有自身定义的可枚举 Symbol 属性会被收集(需用
Object.getOwnPropertySymbols()检测) - getter 属性:若为自身定义且可枚举,解构时会触发 getter 并取其返回值;原型上的 getter 不会被访问
-
不可写/不可配置属性:只要可枚举,仍会被复制到
rest中(值被读取,非引用绑定)
实际建议:避免依赖原型属性做解构
将数据放在实例自身上更可靠、可预测:
- 构造函数或 class 中用
this.x = value显式挂载 - 用
Object.assign(this, data)或展开运算符初始化实例属性 - 若需共享方法,仍放原型;但状态属性(尤其用于解构、序列化、校验的)应属自身

















