2017-08-15 35 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没有那个例子是完全错误的。我会添加一个注释... –