为什么javascript中的数字键总是排序到开头?

use*_*830 5 javascript sorting properties object

因此,假设我在 javascript 中有如下内容:

object = {"one": 1, "two": 2, "three": 3, "123": 123};
Run Code Online (Sandbox Code Playgroud)

当我遍历这个时,结果是“123”成员跳到了列表的最前面,而其他人的顺序保持不变。如果我做类似以下的事情,

object = {"one": 1, "two": 2, "three": 3, "123 STRING": 123};
Run Code Online (Sandbox Code Playgroud)

维持秩序。所以看起来像一个纯粹的数字键被颠倒了,但一个包含非数字字符的键不是。有谁知道为什么?

Esa*_*ija 3

在 V8 中,对象背后的数据结构有很大不同:

  • 对象内命名属性,直接存储在“C 结构体上”
  • 对象外命名属性,存储在对象外部的数组中,额外的间接寻址
  • 索引属性(属性名称可以转换为整数的属性),存储在对象外部的数组中,但数组索引充当键
  • 有序哈希表

命名属性按插入顺序排列,因为这对于隐藏类的演变/转换来说是最自然的。

索引属性按其实际值顺序排列,因为存储插入顺序会浪费内存。

如果您有哈希表支持,则哈希表会故意伪造与自然优化结果相同的顺序。

在其他浏览器中也是如此,因为当数字很小时,在实际的“C 数组”中存储索引属性是一个巨大的优化。可能有所不同的是索引属性是首先列出还是命名属性。

该规范通过不定义迭代顺序使这种优化成为可能,并且 V8 第一个(至少根据该 bug 线程)利用它。

在命名之前列出索引键当然是任意的,反之亦然,不会影响任何优化。