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...

相關文章
相關標籤/搜索