JS 中 Object 的 keys 是无序的吗?
在最开始学习 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
在 ES6 之前 Object 的键值对是无序的;
在 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 是无序的吗?相关推荐
- draft.js_如何使用快捷方式在Draft.js中创建有序列表和无序列表
draft.js by Andrey Semin 通过安德烈·塞米(Andrey Semin) 如何使用快捷方式在Draft.js中创建有序列表和无序列表 (How to create ordered ...
- JS中Object的方法汇总,包括assign、create、prototype等等
JavaScript Object JS的Object到底是啥东西呢?它有啥东西呢? 我们简单知道的,就是new一个Object实例对象,那这个实例对象又何Object又有什么关系呢? 先打印一下看看 ...
- js中Object常用方法和属性
继之前js中数组的常用方法之后,Object的常用方法和属性也是很常用的.故,总结之. 一.属性 Object自带一个prototype的属性,即Object.prototype,Object.pro ...
- php object keys_原生js中Object.keys方法详解
实际开发中,有时需要知道对象的所有属性,原生js提供了一个方法Object.keys(). Object.keys(obj)返回的是一个数组,该数组的所有元素都是字符串.这些元素是来自于给定的obj可 ...
- js中Object类型和Array类型的变量被赋值(复制)给其他变量后,修改被赋值(复制)的新变量的值,会影响原始变量的值,这是为什么呢?
JavaScript中的Object和Array都是指针变量类型,例如我声明 let obj={a:1};let arr=[1,2,3]; 其中的obj和arr存放的仅仅是对应的对象和数组内容所存放的 ...
- Js中Object方法
1.Object.assign() Object.assign()是通过复制一个或多个对象,创建一个新对象. var source1 = { a: 1 }; var source2 = { b: 2 ...
- JS中Object.entries()方法
Object.entries()方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for-in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性). co ...
- js中[object,object]是什么,怎么取值
类型:[object,object]是json类型的 格式:"属性名":"属性值" 如下 可以通过以下的转换,把json类型转换为String类型,看看我们的对 ...
- js中Object.freeze()函数的作用
官方文档 Object.freeze() 方法可以冻结一个对象.一个被冻结的对象再也不能被修改:冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性.可配置性 ...
最新文章
- 追新求快的时代,别让 Java Web 开发必备工具 Tomcat 变成“熟悉的陌生人”!
- mysql 存储过程 锁表_MYSQL锁表问题的解决方法
- Android电量优化全解析
- Echarts柱状图配置
- 获取微信小程序具体链接
- 计算机显示去掉拼音分类,win8系统取消电脑文件显示以字母数字拼音分组的操作办法...
- vue 手机h5动态银行支付密码键盘前端
- 用于退出access的宏命令是_宏操作QuitAccess的功能是什么
- VsCode使用及常用命令汇总(Win10)
- 怎么往日历里面加时钟java,怎样在博客里添加钟表和日历
- 自己整理的Opencore引导版本升级教程【保姆级详细】
- 基于centos搭建物联网服务器,带后台以及数据库(搭建耗时半小时左右)
- 上交所逐笔委托_[转载]上交所、深交所市价委托种类及含义
- table表格,隔行,格列变色
- 昂达v80plus Linux,昂达V80 Plus双系统
- 美通企业日报 | 洽洽开启中国坚果品牌全球化新征程;创维上半年净利同比增两成...
- sci期刊发表流程以及注意事项
- ZYNQ学习之路3. 定制AXI IP核
- TL-WR886N刷OpenWRT(明月大神编译)无线发现不了----正确无线设置
- 健身房软件该如何选择
热门文章
- CF869A The Artful Expedient 结论题+数论
- OkHttp3源码分析二 拦截器 上
- spring集成kafka运行时报错:Failed to construct kafka producer] with root cause
- 捕鱼游戏源码(数值+完整项目资源)
- jieba,为中文分词而生的Python库
- IEEE ICIP 2019 | 更快更好的联邦学习:一种特征融合方法
- Android系统的指纹开发
- java 字体变形_怎样用java绘制弧形文字
- 精品微信小程序预约挂号小程序+后台管理系统|前后分离VUE
- 【Silvaco example】Temperature Ramping - Effect on Leakage