在最开始学习 JavaScript 时,我一直被灌输 Object 中的 Key 是无序的,不可靠的,而与之相对的是 Map 实例会维护键值对的插入顺序。

「But,Object 的键值对真的是无序的吗?」实际上在 ES2015 以后,Object.keys 的规则变了:

在一些现代的浏览器中,keys 输出顺序是可以预测的!

Key 都为自然数:

注意这里的自然数是指正整数或 0,如果是其他类的 Number —— 浮点数或者负数 —— 都会走到下一组类型里,像NaN或者Infinity这种也自然归到下一个类型里,但是像科学记数法这个会稍微特殊一点,感兴趣的同学可以自己试一下。

总结来说,就是当前的 key 如果是自然数就按照自然数的大小进行升序排序。

const objWithIndices = {23: 23,'1': 1,1000: 1000
};console.log(Reflect.ownKeys(objWithIndices)); // ["1", "23", "1000"]
console.log(Object.keys(objWithIndices)); // ["1", "23", "1000"]
console.log(Object.getOwnPropertyNames(objWithIndices)); // ["1", "23", "1000"]

包括在 for-in 循环的遍历中,keys 也是按照这个顺序执行的。

Key 都为 String:

如果 key 是不为自然数的 String(Number 也会转为 String)处理,则按照加入的时间顺序进行排序。

const objWithStrings = {"002": "002",c: 'c',b: "b","001": "001",
}console.log(Reflect.ownKeys(objWithStrings)); // ["002", "c", "b", "001"]
console.log(Object.keys(objWithStrings));// ["002", "c", "b", "001"]
console.log(Object.getOwnPropertyNames(objWithStrings));// ["002", "c", "b", "001"]

Key 都为symbol

const objWithSymbols = {[Symbol("first")]: "first",[Symbol("second")]: "second",[Symbol("last")]: "last",
}console.log(Reflect.ownKeys(objWithSymbols));// [Symbol(first), Symbol(second), Symbol(last)]
console.log(Object.keys(objWithSymbols));// [Symbol(first), Symbol(second), Symbol(last)]
console.log(Object.getOwnPropertyNames(objWithSymbols));// [Symbol(first), Symbol(second), Symbol(last)]

如果 Key 都为 Symbol,顺序和 String 一样,也是按照添加的顺序进行排序的。

如果是以上类型的相互结合

const objWithStrings = {"002": "002",[Symbol("first")]: "first",c: "c",b: "b","100": "100","001": "001",[Symbol("second")]: "second",
}console.log(Reflect.ownKeys(objWithStrings));
// ["100", "002", "c", "b", "001", Symbol(first), Symbol(second)]

结果是先按照自然数升序进行排序,然后按照非数字的 String 的加入时间排序,然后按照 Symbol 的时间顺序进行排序,也就是说他们会先按照上述的分类进行拆分,先按照自然数、非自然数、Symbol 的顺序进行排序,然后根据上述三种类型下内部的顺序进行排序。

Recap

  1. 在 ES6 之前 Object 的键值对是无序的;

  2. 在 ES6 之后 Object 的键值对按照自然数、非自然数和 Symbol 进行排序,自然数是按照大小升序进行排序,其他两种都是按照插入的时间顺序进行排序。

References:

  • 「Property order is predictable in JavaScript objects since ES2015」: https://www.stefanjudis.com/today-i-learned/property-order-is-predictable-in-javascript-objects-since-es2015

  • 「The traversal order of object properties in ES6」: http://2ality.com/2015/10/property-traversal-order-es6.html#traversing-the-own-keys-of-an-object

JS 中 Object 的 keys 是无序的吗?相关推荐

  1. draft.js_如何使用快捷方式在Draft.js中创建有序列表和无序列表

    draft.js by Andrey Semin 通过安德烈·塞米(Andrey Semin) 如何使用快捷方式在Draft.js中创建有序列表和无序列表 (How to create ordered ...

  2. JS中Object的方法汇总,包括assign、create、prototype等等

    JavaScript Object JS的Object到底是啥东西呢?它有啥东西呢? 我们简单知道的,就是new一个Object实例对象,那这个实例对象又何Object又有什么关系呢? 先打印一下看看 ...

  3. js中Object常用方法和属性

    继之前js中数组的常用方法之后,Object的常用方法和属性也是很常用的.故,总结之. 一.属性 Object自带一个prototype的属性,即Object.prototype,Object.pro ...

  4. php object keys_原生js中Object.keys方法详解

    实际开发中,有时需要知道对象的所有属性,原生js提供了一个方法Object.keys(). Object.keys(obj)返回的是一个数组,该数组的所有元素都是字符串.这些元素是来自于给定的obj可 ...

  5. js中Object类型和Array类型的变量被赋值(复制)给其他变量后,修改被赋值(复制)的新变量的值,会影响原始变量的值,这是为什么呢?

    JavaScript中的Object和Array都是指针变量类型,例如我声明 let obj={a:1};let arr=[1,2,3]; 其中的obj和arr存放的仅仅是对应的对象和数组内容所存放的 ...

  6. Js中Object方法

    1.Object.assign() Object.assign()是通过复制一个或多个对象,创建一个新对象. var source1 = { a: 1 }; var source2 = { b: 2 ...

  7. JS中Object.entries()方法

    Object.entries()方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for-in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性). co ...

  8. js中[object,object]是什么,怎么取值

    类型:[object,object]是json类型的 格式:"属性名":"属性值" 如下 可以通过以下的转换,把json类型转换为String类型,看看我们的对 ...

  9. js中Object.freeze()函数的作用

    官方文档 Object.freeze() 方法可以冻结一个对象.一个被冻结的对象再也不能被修改:冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性.可配置性 ...

最新文章

  1. 追新求快的时代,别让 Java Web 开发必备工具 Tomcat 变成“熟悉的陌生人”!
  2. mysql 存储过程 锁表_MYSQL锁表问题的解决方法
  3. Android电量优化全解析
  4. Echarts柱状图配置
  5. 获取微信小程序具体链接
  6. 计算机显示去掉拼音分类,win8系统取消电脑文件显示以字母数字拼音分组的操作办法...
  7. vue 手机h5动态银行支付密码键盘前端
  8. 用于退出access的宏命令是_宏操作QuitAccess的功能是什么
  9. VsCode使用及常用命令汇总(Win10)
  10. 怎么往日历里面加时钟java,怎样在博客里添加钟表和日历
  11. 自己整理的Opencore引导版本升级教程【保姆级详细】
  12. 基于centos搭建物联网服务器,带后台以及数据库(搭建耗时半小时左右)
  13. 上交所逐笔委托_[转载]上交所、深交所市价委托种类及含义
  14. table表格,隔行,格列变色
  15. 昂达v80plus Linux,昂达V80 Plus双系统
  16. 美通企业日报 | 洽洽开启中国坚果品牌全球化新征程;创维上半年净利同比增两成...
  17. sci期刊发表流程以及注意事项
  18. ZYNQ学习之路3. 定制AXI IP核
  19. TL-WR886N刷OpenWRT(明月大神编译)无线发现不了----正确无线设置
  20. 健身房软件该如何选择

热门文章

  1. CF869A The Artful Expedient 结论题+数论
  2. OkHttp3源码分析二 拦截器 上
  3. spring集成kafka运行时报错:Failed to construct kafka producer] with root cause
  4. 捕鱼游戏源码(数值+完整项目资源)
  5. jieba,为中文分词而生的Python库
  6. IEEE ICIP 2019 | 更快更好的联邦学习:一种特征融合方法
  7. Android系统的指纹开发
  8. java 字体变形_怎样用java绘制弧形文字
  9. 精品微信小程序预约挂号小程序+后台管理系统|前后分离VUE
  10. 【Silvaco example】Temperature Ramping - Effect on Leakage