Object.keys只返回对象自身且enumerable为true的字符串键,数字键按数值升序、字符串键按插入顺序排列,Symbol键和不可枚举属性均被忽略。

Object.keys 返回的属性顺序和 enumerable 没有因果关系,但二者共同决定“哪些属性会被返回”以及“以什么顺序出现”。enumerable 控制是否被包含,顺序规则由引擎定义、与属性定义方式有关。
enumerable 决定“进不进场”
Object.keys 只返回对象自身、且 enumerable: true 的属性名。只要 enumerable 为 false,不管键名是什么类型、什么时候定义,都不会出现在结果里。
- 用 Object.defineProperty 显式设为 false 的属性,完全不会被 keys 捕获
- 原型链上的可枚举属性也不出现——keys 只查自身,不查继承
- Symbol 键无论 enumerable 是 true 还是 false,一律忽略
遍历顺序不是由 enumerable 决定的
顺序取决于属性键的类型和定义顺序,与 enumerable 值无关:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 数字键(如 "1"、"100")会按数值升序排列,哪怕后定义
- 字符串键保持插入顺序(ES2015+ 规范保证)
- Symbol 键不参与 keys 排序(因为根本不出现在 keys 结果中)
对比其他方法更能看清区别
同一个对象下,不同方法对 enumerable 和顺序的处理明显不同:
立即学习“Java免费学习笔记(深入)”;
- for...in:受 enumerable 影响(跳过 false),但会遍历原型链;顺序同 keys,但不可靠(规范未强制)
- Object.getOwnPropertyNames:无视 enumerable,所有自身属性都返回;顺序确定(数字升序 + 字符串插入序)
- Reflect.ownKeys:包含 Symbol 和不可枚举属性;顺序与 getOwnPropertyNames 一致
实际写代码时要注意
别依赖 keys 的顺序做逻辑判断,尤其当对象混用数字键和字符串键时。如果顺序关键,建议:
- 统一用字符串键,并按需手动排序(如 keys.sort())
- 需要不可枚举或 Symbol 属性时,改用 getOwnPropertyDescriptors 或 Reflect.ownKeys
- 确认属性是否该被遍历,先检查其 descriptor 中的 enumerable 字段,而不是只看能不能点出来

















