对象字面量创建的属性默认 enumerable 为 true,而 object.defineproperty 定义的属性默认为 false;它影响 object.keys()、for...in、json.stringify() 和 object.assign() 等操作,仅控制是否被遍历而非是否存在。

对象字面量创建的属性,默认 enumerable 为 true。这意味着它们天然支持常见遍历操作,比如 Object.keys()、for...in 循环和 JSON.stringify()。
字面量 vs defineProperty:默认值差异明显
这是最容易混淆的地方——创建方式不同,enumerable 的默认行为完全不同:
- 用
{ a: 1 }或obj.b = 2添加的属性,enumerable自动设为 true - 用
Object.defineProperty(obj, 'c', { value: 3 })定义时,enumerable默认是 false(连同writable和configurable一起)
可枚举性影响哪些操作
enumerable: true 决定属性是否“愿意被列出来”,不是“是否存在”:
-
Object.keys(obj):只返回自有、可枚举的属性名 -
for...in:遍历自身 + 原型链上所有可枚举属性(不含 Symbol) -
JSON.stringify(obj):忽略不可枚举属性,即使它有值 -
Object.getOwnPropertyNames(obj):不受enumerable影响,返回所有自有属性名(包括length、name等内置不可枚举项)
如何验证和修改 enumerable
不能直接改已有属性的 enumerable,只能重定义:
- 查当前值:
Object.getOwnPropertyDescriptor(obj, 'prop')返回描述符,含enumerable字段 - 设为 false:
Object.defineProperty(obj, 'hidden', { value: 42, enumerable: false }) - 批量设置:
Object.defineProperties(obj, { a: { value: 1, enumerable: false }, b: { value: 2, enumerable: true } })
为什么这个细节容易被忽略
因为日常开发中很少手动调用 defineProperty,多数属性都是字面量或赋值添加的,所以 enumerable: true 感觉“理所当然”。但一旦引入库、封装工具方法或做序列化/深拷贝逻辑,不可枚举属性就会悄然漏掉——比如你用 defineProperty 加了个配置字段,却忘了设 enumerable: true,它就不会出现在 Object.keys() 结果里。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











