js for in 排序问题

在意识里一直知道js for in 是无序的,从来没仔细看过具体是怎么样的无序法,
之前看到有同事在做一个需要去重同时排序后取出前三个的场景,
使用了 Object.entries 直接排序一个对象,借助了排序的形式来处理
然后取出前三条数据的使用方式,这里来详细下测试下 for in 的排序问题

测试一些 key 的形式

Object.keys和for in 循环返回顺序一致,这里统一通过keys 测试
只关注 ie9 以上的现代浏览器

纯数字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Object.keys({
3: '3',
4: '4',
312: '312',
2: '2',
12: '12',
1: '1'
})

const chromeOrder = ["1", "2", "3", "4", "12", "312"]; // chrome v70
const nodeOrder = ["1", "2", "3", "4", "12", "312"]; // node v10.16.0
const safariOrder = ["1", "2", "3", "4", "12", "312"]; // safari
const ie11Order = ["1", "2", "3", "4", "12", "312"]; // ie11
const ie9Order = ["1", "2", "3", "4", "12", "312"]; // ie9

现代浏览器都是保持一致,按数字从小到大

数字加英文key混合

1
2
3
Object.keys({ "b3" : "a", "b2" : "b2", "1a": '1a', 7: "c", 4: 'dd'})

// [ '4', '7', 'b3', 'b2', '1a' ] // 以上浏览器都输出相同顺序

现代浏览器依旧保持一致,数字从小到大在最前,其它的按照添加顺序

排序规则

参见: https://segmentfault.com/q/1010000004580095#a-1020000004624835 的回答

  1. 按(integer indices)升序输出
  2. 按添加顺序输出字符串key
  3. 按添加顺序输出 Symbol key (es6 中新加的)

integer indices : 是指将key转化为53bit的无符号整型,然后再转会字符串 后依旧相等的 key。
如 ‘10’, ‘2’ 为integer indices。 ‘01’, ‘12a’ 不是 integer indices。

参考: