不可枚举属性在for...in、object.keys()、json.stringify()和展开运算符中被跳过,仅因enumerable为false;可用object.getownpropertynames()等获取全部自有属性。

JavaScript中不可枚举属性在for...in循环和Object.keys()等遍历方法中默认被跳过,这不是“屏蔽”,而是语言规范定义的行为——这些方法只处理可枚举(enumerable)为true的自有属性。
哪些操作会忽略不可枚举属性
以下内置方法或语法结构天然跳过enumerable: false的属性:
-
for...in循环:只遍历对象自身及原型链上可枚举的属性 -
Object.keys(obj):仅返回对象自身可枚举属性的键名数组 -
JSON.stringify(obj):序列化时忽略不可枚举属性(以及undefined、函数等) - 展开运算符
{...obj}:只拷贝可枚举属性
如何创建不可枚举属性
常用方式是使用Object.defineProperty()显式设置enumerable: false:
const obj = {};<br>Object.defineProperty(obj, 'hidden', {<br> value: 'secret',<br> enumerable: false,<br> writable: true,<br> configurable: true<br>});
此时obj.hidden仍可正常读写,但不会出现在for...in或Object.keys()结果中。
如何访问或遍历不可枚举属性
若需获取全部自有属性(含不可枚举),可用以下方法:
-
Object.getOwnPropertyNames(obj):返回所有自有属性键名(无论是否可枚举) -
Object.getOwnPropertyDescriptors(obj):返回所有自有属性的完整描述符对象,含enumerable字段 -
Reflect.ownKeys(obj):返回所有自有属性键名(包括Symbol类型,也包含不可枚举)
注意:Object.getOwnPropertyNames()和Reflect.ownKeys()都不访问原型链,如需遍历整条原型链上的所有属性(含不可枚举),需手动递归调用Object.getPrototypeOf()。
常见误解与注意事项
不可枚举 ≠ 不可访问,也不等于私有或受保护。它只是控制“是否参与常规遍历”这一行为:
- 不可枚举属性仍可通过点号或方括号直接访问:
obj.hidden或obj['hidden'] - 类中使用
#定义的私有字段(Private Fields)与不可枚举无关,它们根本无法从外部访问,且不挂载在实例对象上 - 多数内置对象(如
Array.prototype的方法)本身是不可枚举的,所以for...in []通常不输出push、map等方法名
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











