14.4 ES6 中遍历属性键

在 ECMAScript 5 中,一个属性的键可以是字符串或者 Symbol 。现在有五种工具方法从 obj 对象中获取属性键:

  • Object.keys(obj) : Array<string>

    获取所有可枚举的自有(非继承)属性的字符串键。

  • Object.getOwnPropertyNames(obj) : Array<string>

    获取所有自有属性的字符串键。

  • Object.getOwnPropertySymbols(obj) : Array<symbol>

    获取所有自有属性的 Symbol 键。

  • Reflect.ownKeys(obj) : Array<string|symbol>

    获取所有自有属性的键。

  • Reflect.enumerate(obj) : Iterator

    获取所有可枚举属性的字符串键。

14.4.1 属性键的迭代顺序

所有迭代属性键的方法都是一样的顺序:

  • 首先是所有的数组索引,按照数字排序。
  • 然后是所有字符串键(非索引),按照创建的顺序。
  • 然后是所有 Symbol ,按照创建的顺序。

注意,语言规范把索引定义为字符串键,当转换成无符号整数然后再转换回来,仍然是同样的字符串(同样也必须比232-1小,因此数组是有长度限制的)。这意味着规范把数组索引看作字符串键,甚至普通的对象都可以有数组索引:

> Reflect.ownKeys({ [Symbol()]:0, b:0, 10:0, 2:0, a:0 })
['2', '10', 'b', 'a', Symbol()]

为什么规范要标准化属性键返回的顺序?

Tab Atkins Jr. 的回答:

因为,至少对于对象,所有在使用中的实现返回的顺序大致和当前的规范一样,并且大量的代码无形中就写成了依赖这种顺序的形式,如果用不同的顺序来枚举的话,将会造成破坏。既然浏览器必须要实现这种特定的顺序来变得 web 兼容,那么规范就要做这种顺序要求。

有一些关于从 Map/Set 中打破这种顺序的讨论,但是这样做的话就需要我们指定一种代码无法依赖的顺序;换句话说,我们必须让顺序是随机的,而不是非指定的。这要做更多的努力,并且创建顺序是很合理的(例如,参考 Python 中的 OrderedDict ),因此决定让 Map 和 Set 和 Object 一样。

规范中有两部分和本节有关:

results matching ""

    No results matching ""