JavaScript 对象遍历方法及其遍历顺序的总结
最近看了《你不知道的 JavaScript(下卷)》,看到了遍历顺序相关的内容(P240),于是作出修改和补充。
2022 / 09 / 19
00. 从规范中定义的算法说起
在 ES6 之前,一个对象属性(键)的列出顺序依赖于浏览器的具体实现,并未在规范中定义。
多数引擎采用的是按照 创建顺序 进行枚举。
ES6 规范新增了一些算法的定义,来规范对象属性的列出顺序。包括:
[[OwnPropertyKeys]]
[[Enumerate]]
(于 ES2016 / ES7 废除),变更为抽象方法EnumerateObjectProperties
。
下面分别介绍这两种算法。
01. [[OwnPropertyKeys]]
1.1 列出属性的范围
这个算法会产生对象的 所有实例属性(即自身拥有的,而非继承来的)。
- 包括 字符串属性 和 Symbol 符号属性。
- 无论是否可枚举。
1.2 使用该算法的方法
这个算法只对以下方法有保证:
Reflect.ownKeys(..)
- 返回由 目标对象 自身的属性键 组成的数组。
- 相当于
Object.getOwnPropertyNames()
与Object.getOwnPropertySymbols()
得到的两个数组进行拼接。
Object.getOwnPropertyNames(..)
- 返回由 目标对象 自身的字符串属性键 组成的数组。
Object.getOwnPropertySymbols(..)
- 返回由 目标对象 自身的 Symbol 属性键 组成的数组。
Object.assign(target, ...sources)
- 将所有 可枚举的 自身的属性 从 一个或多个源对象 复制到 目标对象,返回修改后的对象。
- 其中对于每一个源对象,都使用
[[ownPropertyKeys]]
算法枚举(列出)其属性键,并过滤出可枚举的属性。
1.3 列出顺序
这个算法定义了一个对象属性的列出顺序:
- 先按照 数字上升的排序,枚举所有整数属性。
- 再按 创建顺序 枚举其余的 字符串属性 。
- 最后按 创建顺序 枚举拥有的 Symbol 符号属性。
其中,整数属性的定义为:
- +0 <=
parseFloat(key)
< 2^32 - 1 (最大安全整数) - 不作任何修改便可以与一个整数值相互转换
Stri