2017-08-15 53 views
0

是否使用本地方法之一(map,forEach,reduce,filter等)確定性和標準保證迭代數組的順序?JavaScript數組方法(map,forEach,reduce等)的迭代次序是確定性的嗎?

EG,foo,bar,baz和qux保證是[0, 2, 6, 12]

const a = [1, 2, 3, 4]; 
const foo = a.map((item, index) => item * index); 
const bar = []; a.forEach((item, index) => bar[index] = item * index); 
const baz = []; a.reduce((total, item, index) => baz[index] = item * index, 0); 
const qux = []; a.filter((item, index) => qux[index] = item * index); 
// etc 

(這些是(非常)人爲的例子)

+2

是的,數值屬性按升序進行遍歷。它在語言規範中有明確的描述。 – Pointy

+0

順便說一句,你需要使用一個起始值來減少,就像'a.reduce((total,item,index)=> baz [index] = item * index,null);' –

回答

1

爲數組中存在的每個元素按升序調用回調函數。這是不是呼籲失蹤的元素。 (缺少的元素是,JavaScript的處理稀疏數組?)

var test = []; 
test[30] = 'Test'; // sparse array, only one element defined. 

test.forEach(
    function(value){ 
    console.log(value); // will only be called one time. 
    } 
); 

從標準:ECMA-262

22.1.3.10 Array.prototype.forEach(callbackfn [,thisArg])

注1

callbackfn應該是一個接受三個參數的函數。 for each calls callbackfn對於數組中存在的每個元素按升序排序一次。 callbackfn僅對於實際存在的數組 的元素被調用;它不要求丟失的元件陣列的

如果提供了thisArg參數,它將被用作callbackfn的每個調用的 值。如果沒有提供,則使用undefined代替。

callbackfn使用三個參數調用:元素的值,元素的索引和被遍歷的對象。

的forEach不直接發生變異就調用它,但對象可以通過調用突變成callbackfn的對象。

的forEach方法被調用,一個或兩個參數, 以下是採取措施:

  1. 令O是什麼? ToObject(這個值)。
  2. 讓len是? ToLength(?Get(O,「length」))。
  3. 如果IsCallable(callbackfn)爲false,則拋出TypeError異常。
  4. 如果提供了這個Arg,讓T爲thisArg;否則讓T爲undefined
  5. 設k爲0.
  6. 重複,而k < len a。讓PK成爲!的ToString(K)。灣讓kPresent成爲? HasProperty(O,Pk)。 C。如果kPresent是true,那麼i。讓kValue爲 ?獲取(O,Pk)。 II。表演?調用(callbackfn,T,«kValue,k,O»)。 d。 將k增加1.
  7. 返回undefined
1

通常他們表現得完全像這樣的循環:

for(var i = 0; i < this.length; i++) 

即使世界只有一個例外,reduceRight迭代這樣的:

for(var i = this.length - 1; i+1 ; i--) 

不像上面的例子他們跳過未定義的屬性。

+1

這是真的,但它也是值得的注意數組或類似陣列的對象中的未設置的插槽被跳過。 (通常) – Pointy

+0

不,它們不像循環遍歷每個索引的for循環。它們只遍歷定義的索引。這更像是'input_array = [0,1,2]; input_array [30] = 30; (let keys = Object.keys(input_array),idx = 0,len = keys.length; idx some

+0

@some沒有那個例子是完全錯誤的。我會添加一個註釋... –