object.getownpropertydescriptors用于获取对象所有自有属性的完整描述符,支持深拷贝、代理封装、安全继承等高保真操作,解决object.assign丢失getter/setter等问题。

Object.getOwnPropertyDescriptors 用于一次性获取对象**所有自有属性**的完整描述符,包括 value/writable、get/set、enumerable、configurable 等元信息。它不是 getOwnPropertyDescriptor 的简单数组版,而是为高保真对象操作(如深拷贝、代理封装、安全继承)提供底层支持的关键方法。
解决 Object.assign 丢失 getter/setter 的问题
普通赋值或 Object.assign 只复制属性的“值”,对访问器属性(get/set)完全无效:
- 定义一个含 getter 的对象:
const src = { get name() { return 'Admin'; } }; -
Object.assign({}, src)得到的是空对象,name不再是访问器,调用返回undefined。 - 正确做法:用
getOwnPropertyDescriptors提取全部描述符,再用defineProperties复制:const copy = Object.defineProperties({}, Object.getOwnPropertyDescriptors(src));
此时copy.name仍能正常触发 getter。
批量修改多个属性的 enumerable 状态
想让某些调试字段不在 for...in 或 JSON.stringify 中出现?可统一设为不可枚举:
- 先获取全部自有描述符:
const descriptors = Object.getOwnPropertyDescriptors(obj); - 遍历并修改目标字段:
['_internal', 'cache'].forEach(key => {<br> if (descriptors[key]) {<br> descriptors[key] = { ...descriptors[key], enumerable: false };<br> }<br>}); - 一次性重定义:
Object.defineProperties(obj, descriptors);
创建语义一致的代理对象
在实现响应式系统或日志拦截时,需保留原始属性的所有特性(比如只读性、不可配置性),不能只靠 proxy 拦截 get/set:
- 直接用
getOwnPropertyDescriptors获取源对象描述符; - 将这些描述符传给
Object.defineProperties(proxyTarget, descriptors); - 这样生成的代理对象,在
Object.keys()、Object.getOwnPropertyDescriptor()等行为上与原对象保持一致,避免元信息失真。
配合 defineProperties 实现安全 mixin
传统 mixin 可能覆盖已有属性或破坏原有配置(如把 configurable: false 的属性意外改写)。使用描述符可精确控制:
- 提取要混入的对象的全部描述符;
- 检查目标对象是否已存在同名属性,若存在且
configurable: false,跳过或报错; - 否则调用
Object.defineProperties(target, descriptors),确保每个属性按原始方式定义。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











