对json对象遍历我们一般使用for in循环,或者Object.keys + 数组方法。在接触js以来听到过一种说法:

for in 遍历顺序是不可靠的

但是在实际开发中for in 循环也是按照其键值对的排列先后被遍历,直到遇见了下面的数据:

const data = {
"11": 11,
"2": 2,
"9": 9,
"1": 1
}
var dsd = JSON.stringify(a)
console.log(a); // { '1': 1, '2': 2, '9': 9, '11': 11 }
var keys = Object.keys(a)
console.log(keys); // [ '1', '2', '9', '11' ]
for(var i in a){
console.log(i); 1 2 9 11
}

遍历的时候按照数字从小到大排序了,为什么不能按照给定的顺序输出呢?

在文章5分钟彻底理解Object.keys中作者通过查阅ECMAscript规范,最后提供了如下的结论:

Object.keys在内部会根据属性名key的类型进行不同的排序逻辑。分三种情况:

  1. 如果属性名的类型是Number,那么Object.keys返回值是按照key从小到大排序
  2. 如果属性名的类型是String,那么Object.keys返回值是按照属性被创建的时间升序排序。
  3. 如果属性名的类型是Symbol,那么逻辑同String相同

也就是说在使用到数字型的key的时候,需要特别注意,遍历出来的顺序和想要的可能会不一致

自己也查看了下for in 部分的规范,其中问题出现在 object.[[OwnPropertyKeys]] ,该方法规范地址在这儿,其中就是定义了上面的结论。

直接或者间接使用 object.[[OwnPropertyKeys]]的 API还有如下:

  1. Object.entries 规范地址
  2. Object.values 规范地址
  3. Object.getOwnPropertyNames 规范地址
  4. Reflect.ownKeys 规范地址
  5. Object.keys (规范地址)

json对象遍历顺序问题的更多相关文章

  1. 用递归将嵌套的JSON对象遍历出来,转为二维数组

    如题所示,代码如下: var arJsonNesting = [{id:1,name:"zhang3" ,children:[{id:2,name:"zhang33&qu ...

  2. JS对JSON对象遍历输出的时候真的是按照顺序输出吗?

    对象的遍历输出并不是按照对象属性定义顺序来的,那么是按照什么规则来的呢,仔细深入研究你会发现,这还跟浏览器有关系,Chrome跟IE是不一样的,所以给出以下结论: Chrome Opera 的 Jav ...

  3. JSON对象遍历方法

    JSON对象提前不知道其属性和结构,遍历其值 var json2 = { "name": "txt1", "name2": "tx ...

  4. Json对象遍历

    var json = {"id":"123","name":"tom","sex":"ma ...

  5. 用递归将嵌套的JSON对象遍历出来,转为二维数组 或一维数组

    var map = new Array();//二维数组 var map2 = new Array();//一维数组 for (var i = 0; i < e.Data.length; i++ ...

  6. js对象遍历输出顺序错乱的问题

    一.js对象遍历顺序错乱的原因 下边就来实践一下: var obj={'3':'ccc',name:'abc',age:23,school:'sdfds',class:'dfd',hobby:'dsf ...

  7. js遍历json对象

    原生js遍历json对象 遍历json对象: 无规律: <script> var json = [ {dd:'SB',AA:'东东',re1:123}, {cccc:'dd',lk:'1q ...

  8. JS JSON对象相关

    1.多对象合并 将2个或2个以上对象(object{....})中的属性进行合并,即最后合并为一个object{.....} 解决办法:Object.assign 方法 var form = {nam ...

  9. JSON数组,JSON对象,数组的区别与基本操作整理

    JSON 语法规则 JSON 语法是 javascript 对象表示语法的子集. 数据在名称/值对中 数据由逗号分隔 花括号保存对象 方括号保存数组 JSON 名称/值对 JSON 数据的书写格式是: ...

随机推荐

  1. SpringBoot学习之整合Mybatis

    本博客使用IDEA开发工具,通过Maven构建SpringBoot项目,初始化项目添加的依赖有:spring-boot-starter-jdbc.spring-boot-starter-web.mys ...

  2. 《分享》Graphql入门与实践

    最近项目用到了graphql,学习了一些并在公司做了一个小分享,希望对你有帮助 一.介绍 Graphql是一种面向数据的API查询语言 Graphql给前端提供一种强力的查询工具,我们可以根据自己定义 ...

  3. tracebace用法

    介绍一下traceback 平时看到的程序的错误信息也就是traceback信息 举个简单例子: import traceback try: s = [1, 2, 3] print s[5] exce ...

  4. 自身写Android组合多个布局的经历

    今天不总结课程了,留着有时间补上. 今天的是ExpandListView,就是可以扩展的列表视图. 今天我做了个总结,然后模仿了扣扣的聊天界面,仅仅写了三个页面而已,用到的xml和活动就不下于10个, ...

  5. JS 鼠标放上去滑出内容案例

    .sliderbar { width: 200px; height: 40px; position: relative; margin: 0 auto; } .sliderbar span { dis ...

  6. 19、Java 序列化

    1.序列化的概念,意义以及使用场景 序列化: 将对象写入到IO流中,也就是把Java对象转换为字节序列的过程 反序列化: 从IO流中恢复对象*,也就是把字节序列恢复为Java对象的过程 意义: 序列化 ...

  7. Vue + ccropper.js裁切图片(vue-cropper)

    按原比例裁剪图片并且不失真. 安装: cnpm install vue-cropper --save-dev 使用: <template> <div style="disp ...

  8. 关于setTimeout的用法注意事项

    setTimeout setTimeout的定义:setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式. setTimeout的用法:setTimeout(代码片段,执行代码等待的毫 ...

  9. 企业微信人员日程推送接口(python版)

    企业在使用企业微信中,有时想批量推送员工日程信息.这里写了个接口工具分享给大家,供交流学习. 主入口程序: # -*- coding: utf-8 -*-import time as time imp ...

  10. Js中的各种高度问题

    一.屏幕宽高相关 屏幕高度就是你的整个屏幕高度(开机会亮的那片区域的高度),相关的其他高度划分很简单,就是以任务栏为分界线从而分为两部分. screen.height :屏幕高度. screen.wi ...