2014-01-09 48 views
0

最近我發現在Firefox這奇怪的行爲:的Javascript自動排序在Firefox VS其他瀏覽器

此代碼自動排序的屬性:

var an_obj = { "4": "d", "1": "a", "2": "c"}; 
alert(Object.keys(an_obj)); // will alert "1, 2, 4" 

雖然這個人是不是:

var value2 = {"1003":1, "1001":2, "1000":3}; 
alert(Object.keys(value2));// will alert "1003, 1001, 1000" 

任何大於1000的數字在Firefox中將具有不同的行爲,而其他瀏覽器(Chrome,IE11)的行爲與預期的大於1000的自動分類數量相同。

我相信這是FireFox中的一個錯誤,我錯了嗎?

更新1

這使得相同的實現火狐內的秩序「不可預測的」。我可以理解根本不會排序的值,或者根據一個標準排序,但不會在「任意」數字後表現「不可預測」。

回答

6

這不是一個錯誤。對象不保證其屬性中的任何順序,並且在某些情況下不應該依賴任何與Object.keys訂購。

它在§15.2.3.14 ECMAScript 5 standardObject.keys

如果一個實現定義枚舉的特定順序對換在聲明,相同的枚舉順序必須在該算法的步驟5中使用的說明。

這意味着for-in聲明和Object.keys的任何排序都完全依賴於實現。

+0

但行爲是不是一致的,但在這種情況下一些值的一種方式,而不是不穩定的工作值大於1000,爲什麼其他瀏覽器的行爲邏輯和排序和Firefox不是? – Dalorzo

+0

@Dororzo因爲不需要瀏覽器來對鍵進行排序。其他瀏覽器可能會這樣做,但ECMAScript規範中沒有要求他們這樣做。 –

+0

但這是在Firefox的相同的實現裏有同樣的行爲有2個行爲 – Dalorzo

2

ECMAScript standard沒有定義的排序由Object.keys返回的屬性,而是留下多達實現:

如果實現定義枚舉爲 換在聲明特定的順序,該算法的步驟5 必須使用相同的枚舉順序。

至於由火狐,MDN states使用的特定實現:

屬性的順序是相同的,通過遍歷對象的手動性質給出。

事實上,如果你嘗試,你會看到,這確實是這樣的:

for(var o in {"1003":1, "1001":2, "1000":3}) 
    console.log(o); 
// 1003, 1001, 1000 

沒有其他擔保對該結果的排序。換句話說,這不是一個錯誤,它只是不同實現本質的一部分。但如果你願意的話,你可以把它叫做怪癖

+0

對於所有的值,包括低於1000的值,都是如此。但它不是這樣工作的,不是嗎? – Dalorzo

+0

@Dororzo問題是,不同的實現可以按照他們認爲合適的順序返回它們。你不應該期望它在所有的實現中都是一致的。 –

+0

但這是在同一個執行的Firefox內有2個行爲爲同一行動 – Dalorzo

0

您可以使用排序來修復不可預知的行爲。我假設你已經知道了這一點,並試圖讓一個可能的錯誤反饋,但如果你不這樣做,或者別人需要知道:

var value2 = {"1003":1, "1001":2, "1000":3}; 
var sorted = Object.keys(value2); 
sorted.sort(); 
alert(sorted); 

呈現在Firefox預期時尚的值。

1

我想添加到我自己的問題,我能發現有人已提交了該行爲,火狐團隊:

如正確地@Peter Olson和@pswg解釋的答案是:

是的,枚舉排序是未指定的。不要依賴它!

ES7應該糾正這個問題,而關於這個問題的最終決定是硬着頭皮讓它解決不了。

爲有興趣在這個人,你可以找到完整的參考這裏:

https://bugzilla.mozilla.org/show_bug.cgi?id=865760

相關問題