enumerable 控制属性是否可被 for...in 枚举及 object.keys()、json.stringify() 等 api 访问;设为 false 后属性不可枚举但仍可读写,for...in 仅遍历 enumerable: true 的自有和继承属性,默认字面量属性 enumerable 为 true,object.defineproperty() 默认为 false。

属性描述符中的 enumerable 控制该属性是否可被 for...in 循环枚举,也影响 Object.keys()、JSON.stringify() 等 API 的行为。设为 false 后,该属性不会出现在这些遍历操作中,但依然可以正常读写(除非同时设 writable: false 或 configurable: false)。
enumerable 与 for-in 的关系
for...in 只遍历对象自身及原型链上 可枚举(enumerable: true) 的自有属性和继承属性。只要某属性的 enumerable 为 false,无论它在对象自身还是原型上,都不会被 for...in 访问到。
- 默认情况下,使用字面量或赋值创建的属性,
enumerable都是true - 通过
Object.defineProperty()定义的属性,默认enumerable为false - 用
Object.defineProperties()或class中的 getter/setter 定义时,需显式设置enumerable
手动控制 enumerable 的常见方式
最常用的是 Object.defineProperty():
const obj = {};
Object.defineProperty(obj, 'hidden', {
value: 'secret',
enumerable: false, // 关键:设为 false
writable: true,
configurable: true
});
obj.visible = 'shown'; // 字面量添加,enumerable 默认 true
for (let key in obj) {
console.log(key); // 只输出 'visible',不输出 'hidden'
}
也可批量设置:
Object.defineProperties(obj, {
a: { value: 1, enumerable: false },
b: { value: 2, enumerable: true }
});
注意 enumerable 对其他 API 的影响
enumerable: false 不仅影响 for...in,还会影响:
-
Object.keys(obj):只返回enumerable: true的自有属性名 -
JSON.stringify(obj):忽略enumerable: false的属性(即使可访问) -
for...of+Object.entries()或Object.getOwnPropertyNames():前者受 enumerable 影响,后者不受(它返回所有自有属性名,不管 enumerable)
如何检查一个属性是否可枚举
用 Object.getOwnPropertyDescriptor() 查看描述符:
const desc = Object.getOwnPropertyDescriptor(obj, 'hidden'); console.log(desc.enumerable); // false
或者用 Object.prototype.propertyIsEnumerable() 快速判断(只查自有属性):
obj.propertyIsEnumerable('hidden'); // false
obj.propertyIsEnumerable('visible'); // true











