Object.keys()是按什么顺序返回值的?

碰到了一个颇有意思的问题,js中对象属性的输出是有序的吗?若是有的话,那又遵循怎样的规则呢?javascript

这里咱们来作一个简单的探讨,工做之余来一点趣味性的问题。虽不能醍醐灌顶,但能够巩固所学知识,也是极好的~🙈java

1、奇怪现象

咱们来看这样一个对象,来输出他的属性名称,也就是key值:segmentfault

var data = {'1':'aaa','2':'bbb','3':'ccc','测试':'000'};
Object.keys(data) ;

["1", "2", "3", "测试"]

嗯,没啥问题。那调整一下最后一项的位置,再来试试:数组

var data = {'测试':'000','1':'aaa','2':'bbb','3':'ccc'};
Object.keys(data);

["1", "2", "3", "测试"]

奇怪,输出的顺序被调整了,这是为何呢?咱们继续,换一下属性名称,再试一次:浏览器

var data = {'a':'000','1':'aaa','2':'bbb','3':'ccc'};
Object.keys(data);


["1", "2", "3", "a"]

依结果来看,貌似有点小规律,咱们不妨猜一下。测试

2、大胆猜想

咱们来看结果:url

["1", "2", "3", "测试"]
["1", "2", "3", "a"]

会不会是按照ASC码的大小顺序来输出的呢?code

'1'<'2'<'3'<'测试'
'1'<'2'<'3'<'a'

好像漏掉了一种状况(字母和汉字的属性名称同时存在),咱们试一下:对象

var data = {'a':'000','3':'ccc','1':'aaa','测试':'bbb',};
Object.keys(data);

["1", "3", "a", "测试"]

调整属性’a’和’测试’的顺序呢?排序

var data = {'测试':'bbb','3':'ccc','a':'000','1':'aaa'};
Object.keys(data);


["1", "3", "测试", "a"]

好了,到此为止,咱们能够得出结论了。

结论:对象的遍历输出并非按照属性的ASC码升序排序的。

3、初见端倪

查阅了一些文档后,得出了如下有效结论:

1.An object is a member of the type Object. It is an unordered collection of properties each of which contains a primitive value,
object, or function. A function stored in a property of an object is
called a method.

2.Chrome Opera 的 JavaScript 解析引擎遵循的是新版 ECMA-262 第五版规范。所以,使用 for-in 语句遍历对象属性时遍历书序并不是属性构建顺序。而 IE6 IE7 IE8 Firefox Safari 的 JavaScript
解析引擎遵循的是较老的 ECMA-262 第三版规范,属性遍历顺序由属性构建的顺序决定。

4、真相大白

Chrome Opera 中使用 for-in 语句遍历对象属性时会遵循一个规律:

它们会先提取全部 key 的 parseFloat 值为非负整数的属性,而后根据数字顺序对属性排序首先遍历出来,而后按照对象定义的顺序遍历余下的全部属性。

其它浏览器则彻底按照对象定义的顺序遍历属性。
这和咱们上面例子中的数据结果是吻合的,嗯,这就是我想要的结果!

5、结案总结

若是想顺序遍历一组数据,请使用数组并使用 for 语句遍历。

for-in语句没法保证遍历顺序,应尽可能避免编写依赖对象属性顺序的代码。若是想按照定义的次序遍历对象属性,请参考这里针对各浏览器编写特殊代码。

因为对象的输出是无序的,可是数组倒是有序的,因此为了保证顺序,搞成数组再输出。嗯,就是这样!

6、参考文档
1.ASCII参照表
http://baike.baidu.com/link?u...
2.js对象输出顺序
http://stackoverflow.com/ques...
3.遍历出的属性顺序与对象定义时不一样
http://w3help.org/zh-cn/cause...
4.控制js中的对象顺序输出
https://segmentfault.com/q/10...

相关文章
相关标签/搜索