2012-11-28 42 views
17

在javascript中我可以有孔的陣列:是否按升序排列的JavaScript array.forEach遍歷元素

a = []; 
a[0] = 100; 
a[5] = 200; 
a[3] = 300; 

a.forEach(function(x) {alert(x);}); 

我找不到任何關於是否將元素以升序進行處理或者這是不可靠的事實信息。

我檢查「for .. in」循環遍歷數組索引按升序排列,而對象的屬性名以相同的順序遍歷它們被添加到對象(至少看起來如此)。

(即它看起來像陣列內部某種樹木和對象是哈希表)。

我剛剛發現犀牛的JavaScript穿越不存在的元素也: http://ideone.com/7Z3AFh(不同的for..in)。

回答

25

ECMA-262, 5th edition規範和MDN's Array.forEach() page都顯示.forEach()的算法,並且它肯定會按升序索引順序遍歷數組元素(跳過從未指定值的索引)。

當然,有些瀏覽器可能無法正確實現該算法,但我不知道有沒有。

+0

嗯。我之前幾次讀過它,只是現在看到我不注意。謝謝。這種方法根本不會穿越內部結構,因爲我看到...... :( –

2

直出ECMAScript standard

的foreach呼叫callbackfn一次爲每個存在於陣列, 以升序在元件。僅對 數組中實際存在的元素調用callbackfn;它不會被要求丟失數組 。

所以Array.forEach會跳過數組中的某些元素。你的榜樣

a.forEach(function(value) { console.log(value) }); // prints 100, 300, 200 

如果你想遍歷升序排列,所有的元素是數字,那麼你就可以在陣列事先進行排序,像這樣

a.sort(function(a, b) { return a - b }); 
// this now prints 100, 200, 300 
a.forEach(function(value) { console.log(value) }); 
+0

但問題是否迭代_order_是否有保證。 – nnnnnn

+0

你仍然錯了 - 訂單將是'100,300,200' – Ian

+0

感謝您的。已更正 – Bruno

12

The specification saysforEach將訪問數組元素數字順序。它不訪問不存在的元素。詳情請參閱鏈接。因此,對於您的示例數組,它將訪問元素0,然後3,然後5。將它們添加到數組的順序對它們訪問的順序沒有影響。

我檢查到「for .. in」循環以升序排列數組索引,而對象的屬性名以相同順序遍歷(至少看起來像這樣)。

其中for-in訪問對象屬性的順序是不由規範所定義,甚至沒有在ES2015(又名ES6),儘管事實上,ES2015 defines an order for object properties   —該順序並不適用於for-inObject.keys 。 (更多關於this answer的信息。)如果您想按照ES2015中定義的順序訪問屬性,可以使用Object.getOwnPropertyNames(對於未用Symbol名稱定義的屬性)或Reflect.ownKeys(對於Symbol和字符串屬性名稱[記住數字屬性名稱真的是字符串])。這兩種尊重屬性的順序。

+0

Chrome在執行Object.getOwnPropertyNames和Reflect.ownKeys時,現在按數字順序排序。我可以找到的*不*排序它們的唯一方法是通過在鍵的開頭預先加上一個'_'來使它們成爲非數字字符串。 – Mike

+0

@Mike:是的。遵循這個規範,他們提出*不*要求供應商在'for-in'和'Object.keys'上支持該順序,我認爲如果供應商有足夠的理由保持目前的幾個版本的順序。但我認爲在實踐中,供應商一直都很樂意保持一致,並保持一致。 –