Object.keys的遍历顺序

248 阅读4分钟

image.png

先上结论

有规律可以寻,但不友好

所以不建议使用对象的形式做有序的排序,除非你可以用sort重新整理好😂,不然容易G

下面代码可以直接复制放在控制台运行😆

代码验证

key直接是数字

  • 这个数字是指
    • 字符串:可以转为数字的,但是不需要额外改的
      • 0算,00就不算
    • 数字
const data = {
  "-1": "-1",
  "0": "0",
  "1": "1"
}
console.log(data);
const arr = Object.keys(data)
console.log(arr)
const json = JSON.stringify(data)
console.log(json)

结果

image.png

我们肯定期待key输出的顺序是-1,0,1,结果不是,现代js引擎一定会把数字排序,负数放后面

看似数字,其实不是

const a = {'-01': '-1'}
const b = {'00': '0'}
const c = {'01': '1'}
const data = Object.assign({},a,b,c)
console.log(data)
const arr = Object.keys(data)
console.log(arr)

结果

image.png

这个又是正常的,人都要裂开💔

数字和字符混用

const a = {'-1': '-1'}
const b = {'test': '0'}
const c = {'1': '1'}
const data = Object.assign({},a,b,c)
console.log(data)
const arr = Object.keys(data)
console.log(arr)

结果

image.png

数字的一定会在字符的前面

key全是中文也会对不上

const res = {
  "code": "0", "data": {
    "变更签证文件": [],
    "招标文件": [],
    "中标文件": [{
      "id": "1078402032953458688",
      "attId": "4c89524740d24e73a297f394fcfe93c4",
      "fileType": "中标文件",
      "fileName": "用户需求说明书v2.0(1).doc",
      "uploadDate": "2023-02-23 19:44:40"
    }],
    "收付款文件": [],
    "施工合同文件": [{
      "id": null,
      "attId": "a7b76df398704602bb30514a3bc28250",
      "fileType": "施工合同文件",
      "fileName": "【二维码】2200096山东麟祥(济宁西)500千伏输变电工程施工合同.doc",
      "uploadDate": "2023-02-26 10:21:00"
    }, {
      "id": null,
      "attId": "5a5a6cdd36614300bfbfd65e818dcde6",
      "fileType": "施工合同文件",
      "fileName": "【二维码】2200096山东麟祥(济宁西)500千伏输变电工程施工合同.doc",
      "uploadDate": null
    }, {
      "id": null,
      "attId": "5a5a6cdd36614300bfbfd65e818dcde6",
      "fileType": "施工合同文件",
      "fileName": "【二维码】2200096山东麟祥(济宁西)500千伏输变电工程施工合同.doc",
      "uploadDate": null
    }, {
      "id": null,
      "attId": "5a5a6cdd36614300bfbfd65e818dcde6",
      "fileType": "施工合同文件",
      "fileName": "【二维码】2200096山东麟祥(济宁西)500千伏输变电工程施工合同.doc",
      "uploadDate": null
    }],
    "补偿合同文件": [{
      "id": null,
      "attId": "5cd82d2e44c64e389dabf7871250ef0f",
      "fileType": "补偿合同文件",
      "fileName": "评审文件(1) (1).doc",
      "uploadDate": "2023-03-07 13:35:08"
    }],
    "服务合同文件": [],
    "机械承揽合同文件": [{
      "id": null,
      "attId": "9ad9a74374e34e2da175f4a5e47c59ac",
      "fileType": "机械承揽合同文件",
      "fileName": "评审文件(1) (2).doc",
      "uploadDate": "2023-03-07 10:57:43"
    }],
    "结算文件": [],
    "物资合同文件": [],
    "租赁合同文件": [{
      "id": null,
      "attId": "b03a62e51a8f4cc7860d90a41cfbd30f",
      "fileType": "租赁合同文件",
      "fileName": "评审文件(1) (2).doc",
      "uploadDate": "2023-03-10 10:35:37"
    }, {
      "id": null,
      "attId": "dc7100a4204d421d85d09a364bdc6b78",
      "fileType": "租赁合同文件",
      "fileName": "黄毛.docx",
      "uploadDate": "2023-03-09 09:43:20"
    }, {
      "id": null,
      "attId": "e56a90985bf84d259a83d40181a12871",
      "fileType": "租赁合同文件",
      "fileName": "评审文件(1) (1).doc",
      "uploadDate": "2023-03-09 09:41:12"
    }, {
      "id": null,
      "attId": "5a82cf12ed7f42a38f0817bd45b21591",
      "fileType": "租赁合同文件",
      "fileName": "评审文件(1) (2).doc",
      "uploadDate": "2023-03-09 09:37:18"
    }],
    "分包合同文件": [],
    "投标文件": [{
      "id": "1078401725456449536",
      "attId": "8da3a5b438a5493794fcd6d1c63f7d33",
      "fileType": "投标文件",
      "fileName": "评审文件(1) (2).doc",
      "uploadDate": "2023-02-23 19:43:27"
    }]
  }, "msg": "操作成功"
}
const data = res.data
console.log(data)
const arr = Object.keys(data)
console.log(arr);

结果

image.png

这个结果又完全是不一样的,让人摸不着头脑,对象在控制台中key的顺序是不对的,但是key的遍历却是对的

image.png

标准参考

根据 ECMA-262(ECMAScript)第三版中描述,for-in 语句的属性遍历的顺序是由对象定义时属性的书写顺序决定的

在现有最新的 ECMA-262(ECMAScript)第五版规范中,对 for-in 语句的遍历机制又做了调整,属性遍历的顺序是没有被规定的

新版本中的属性遍历顺序说明与早期版本不同,这将导致遵循 ECMA-262 第三版规范内容实现的 JavaScript 解析引擎在处理 for-in 语句时,与遵循第五版规范实现的解析引擎,对属性的遍历顺序存在不一致的问题。

最后

欢迎关注公众号致心空间:O(∩_∩)O😁

致心空间

参考

js中关于for...in遍历对象属性的顺序问题