当对象属性的 enumerable 设为 false 时,它不会出现在 {...obj}、object.assign()、json.stringify() 和 for...in 中,但可通过直接访问、object.getownpropertynames() 等方式读写。

当对象属性的 enumerable 设为 false 时,它不会出现在对象扩展(即展开运算符 {...obj})中,也不会被 Object.assign() 拷贝。这不是“不可访问”,而是“不参与枚举型复制”——属性依然存在、可读可写,只是被刻意排除在遍历和浅拷贝逻辑之外。
哪些扩展操作会忽略 enumerable: false 的属性
以下操作依赖属性的可枚举性,遇到 enumerable: false 会直接跳过:
-
{...obj}展开运算符:只提取自身可枚举属性 -
Object.assign(target, obj):只拷贝自身可枚举属性 -
JSON.stringify(obj):不序列化不可枚举属性(以及函数、undefined、Symbol) -
for...in循环:遍历自身 + 原型链上所有可枚举属性,不可枚举的一律跳过 -
Object.keys(obj):仅返回自身可枚举属性名数组
哪些操作不受 enumerable 影响,仍能访问到
这些方式不依赖枚举性,能完整触及属性(包括不可枚举的):
- 直接访问:
obj.prop或obj["prop"]—— 可正常读写 -
Object.getOwnPropertyNames(obj)—— 返回所有自身属性名(含不可枚举) -
Reflect.ownKeys(obj)—— 返回所有自身键(含不可枚举、Symbol) -
Object.getOwnPropertyDescriptors(obj)—— 获取全部自身属性描述符
如何设置 enumerable: false
不能通过字面量或赋值语法设置,必须使用属性描述符 API:
Object.defineProperty(obj, 'key', { value: 123, enumerable: false })Object.defineProperties(obj, { key1: { value: 1, enumerable: false }, key2: { value: 2, enumerable: true } })
注意:普通对象字面量创建的属性默认 enumerable: true;类方法、内置原型方法(如 Array.prototype.map)默认 enumerable: false。
常见误用与排查建议
遇到扩展后“丢失属性”,先确认是否被设为不可枚举:
- 用
Object.getOwnPropertyDescriptors(obj)查看目标属性的enumerable值 - 用
obj.propertyIsEnumerable('key')快速判断(注意:该方法对继承属性始终返回false) - 避免在需要结构克隆的场景(如状态合并、props 透传)中将关键字段设为不可枚举
- 若需保留不可枚举语义但又希望参与扩展,可用
Reflect.ownKeys(obj).reduce(...)手动构造新对象
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











