enumerable 是属性描述符中的布尔值,决定属性是否可被 for...in、object.keys()、json.stringify() 等遍历操作访问,默认 true,设为 false 后仍可读写但不参与常规遍历。

JavaScript 中通过 enumerable 属性控制属性是否出现在 for...in 循环、Object.keys()、JSON.stringify() 等遍历操作中。它属于属性描述符(property descriptor)的一部分,决定该属性是否“可枚举”。
什么是 enumerable 属性
enumerable 是一个布尔值,表示该属性是否能被枚举——即是否会被常规的属性遍历方法访问到。默认为 true(如直接赋值创建的属性),但可通过 Object.defineProperty() 或 Object.defineProperties() 显式设为 false。
- 设为
false后,该属性不会出现在for...in、Object.keys()、Object.getOwnPropertyNames()(注意:getOwnPropertyNames仍会返回,因为它不关心 enumerable,只关心是否存在)、JSON.stringify()中 - 但它依然可读、可写(除非同时设
writable: false)、可配置(除非configurable: false) -
Object.getOwnPropertyDescriptor()总能获取到该属性的完整描述符,无论enumerable值如何
如何设置 enumerable 为 false
使用 Object.defineProperty() 是最常用方式:
const obj = { a: 1 };
Object.defineProperty(obj, 'b', {
value: 2,
enumerable: false, // 关键:设为 false
writable: true,
configurable: true
});
console.log(obj.b); // 2 → 可正常访问
console.log(Object.keys(obj)); // ['a'] → 'b' 不出现
for (let key in obj) console.log(key); // 只输出 'a'
JSON.stringify(obj); // '{"a":1}'
enumerable 对不同遍历方式的影响
不同 API 对 enumerable 的敏感度不同,需注意区分:
-
Object.keys():只返回enumerable === true的自有属性 -
Object.getOwnPropertyNames():返回所有自有属性(不管enumerable),包括enumerable: false的 -
for...in:遍历自身 + 原型链上enumerable === true的属性 -
JSON.stringify():只序列化enumerable === true的自有属性 -
Reflect.ownKeys():类似getOwnPropertyNames(),返回所有自有属性键(含 Symbol),无视enumerable
实际应用场景
常用于隐藏内部状态或避免污染序列化/遍历结果:
- 定义私有缓存字段(如
_cache),设enumerable: false防止被意外遍历到 - 在类或构造函数中,用
defineProperty添加不可枚举的方法或元数据 - 封装库时,把配置项或调试标记设为不可枚举,保持
Object.keys(instance)干净 - 配合
Symbol使用时注意:Symbol 属性默认enumerable也为false,所以天然不参与常规遍历
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











