enumerable 是属性描述符中控制是否参与遍历的开关,设为 false 后属性仍可直接读写,但会被 for...in、object.keys()、json.stringify()、扩展运算符和 object.assign() 忽略;对象字面量默认 enumerable: true,object.defineproperty 默认 false。

enumerable 是属性描述符中决定“该属性是否参与遍历”的开关,它不控制能否访问,只控制是否出现在 for...in、Object.keys()、JSON.stringify() 等枚举操作里。
enumerable 如何影响常见枚举行为
设为 false 后,属性依然能通过点号或方括号直接读写,但会被以下操作忽略:
-
for...in循环:跳过该属性(无论自有还是继承) -
Object.keys(obj):不包含它(只返回自有可枚举属性) -
JSON.stringify(obj):序列化结果中完全不出现 - 扩展运算符
{...obj}和Object.assign({}, obj):不会复制该属性
默认值取决于创建方式
不同方式定义属性,enumerable 的初始值不同,这是最容易出错的地方:
- 对象字面量
{ a: 1 }:所有属性默认enumerable: true -
Object.defineProperty(obj, key, { value }):不显式设置时,默认enumerable: false -
Object.defineProperties(obj, { ... }):每个属性都需单独指定,否则也默认false
如何显式设置 enumerable
最可靠的方式是用 Object.defineProperty 或 Object.defineProperties 明确传入 enumerable 值:
- 单个属性:
Object.defineProperty(obj, 'id', { value: 100, enumerable: false }) - 多个属性:
Object.defineProperties(obj, { a: { value: 1, enumerable: false }, b: { value: 2, enumerable: true } }) - 批量隐藏已有属性:先用
Object.getOwnPropertyNames(obj)获取所有自有属性名,再逐个重定义并设enumerable: false
enumerable 与原型链和 hasOwnProperty 的关系
它只看属性自身的 enumerable 值,和定义位置无关:
- 原型上的属性只要
enumerable: true,就会被for...in遍历到 -
hasOwnProperty()判断的是“是否为自有属性”,和enumerable无关——一个属性可以是自有且不可枚举的 -
Object.keys()只查自有可枚举属性;for...in查自有 + 原型链上所有可枚举属性
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











