JavaScript对象属性遍历有严格顺序规范:整数索引键按数值升序,字符串键按插入顺序,Symbol键排最后且按插入顺序;Reflect.ownKeys()稳定体现该顺序,而for...in和Object.keys()不保证;各API覆盖范围不同,需据需求选用。

属性遍历的三类键顺序有严格规则
从ES2015起,对象自有属性(own properties)的逻辑顺序被明确定义:
- 整数索引键(如"0"、"1"、"10"):按数值升序排列,不看字符串字典序
- 普通字符串键(非整数索引):严格按插入顺序,不是字母序
- Symbol键:统一排在所有字符串键之后,也按插入顺序
注意:这个顺序只在 Reflect.ownKeys() 和手动组合 Object.getOwnPropertyNames() + Object.getOwnPropertySymbols() 时才稳定体现。而 for...in 和 Object.keys() 不承诺遵守该顺序,尤其在涉及原型链或旧引擎时。
不同遍历方法覆盖的属性类型不同
每种API都有明确的“可见范围”,不能混用:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
for...in:只遍历可枚举属性(自身+原型链),跳过Symbol和不可枚举属性 -
Object.keys():仅自身可枚举字符串键,最常用但最窄 -
Object.getOwnPropertyNames():自身所有字符串键(含不可枚举),不含Symbol -
Object.getOwnPropertySymbols():仅自身Symbol键 -
Reflect.ownKeys():最全——自身所有键(字符串+Symbol+不可枚举),顺序符合ES规范
检查属性是否存在,方法选错就容易误判
判断“某属性是否在对象上”不能只靠 in 或 == null,得看你要查什么:
立即学习“Java免费学习笔记(深入)”;
-
'key' in obj:查**整个原型链**上的任意可/不可枚举属性(含Symbol) -
obj.hasOwnProperty('key')或Object.hasOwn(obj, 'key')(推荐):只查**自身**属性,不管是否可枚举,也不管是字符串还是Symbol -
obj.propertyIsEnumerable('key'):专门判断该属性是否为**自身且可枚举** -
obj.key !== undefined:不安全!值可能是undefined,无法区分“不存在”和“显式赋了undefined”
需要完整有序遍历?推荐组合方案
若你既要所有自有属性,又要保持标准顺序(整数→字符串→Symbol),不要依赖单一API:
- 先用
Reflect.ownKeys(obj)—— 它天然返回规范顺序,且包含全部键 - 或者手动合并:
[...Object.getOwnPropertyNames(obj), ...Object.getOwnPropertySymbols(obj)],二者各自内部都按规范排序 - 遍历时记得用
obj[key]取值,对Symbol键也完全适用

















