javascript数组方法(map,forEach,reduce等)的迭代顺序是否确定?

时间:2017-08-15 19:04:29

标签: javascript arrays iteration specifications deterministic

是否使用其中一种本地方法(map,forEach,reduce,filter等)迭代数组的顺序是否具有确定性且由标准保证?

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 个答案:

答案 0 :(得分:1)

通常它们的行为与循环完全相同:

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

只有一个例外, reduceRight 迭代如下:

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

与上面的示例不同,它们会跳过未定义的属性。

答案 1 :(得分: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 应该是一个接受三个参数的函数。    forEach 按升序为数组中的每个元素调用 callbackfn 一次。仅为元素调用 callbackfn   实际存在的数组;没有要求缺少元素   数组

     

如果提供了 thisArg 参数,则将其用作   每次调用 callbackfn 值。如果未提供,则使用 undefined

     使用三个参数调用

callbackfn :值的值   元素,元素的索引和被遍历的对象。

     

forEach 不直接改变调用它的对象,但是对象可能会被调用 callbackfn 而变异。

     

当使用一个或两个参数调用 forEach 方法时,   采取以下步骤:

     
      
  1. 让O成为? ToObject(此值)。
  2.   
  3. 让len成为? ToLength(?Get(O,“length”))。
  4.   
  5. 如果IsCallable(callbackfn) false ,则抛出 TypeError 异常。
  6.   
  7. 如果提供thisArg,则让T为thisArg;否则让T 未定义
  8.   
  9. 设k为0。
  10.   
  11. 重复,而k < len a。让Pk成为!的ToString(K)。湾让kPresent成为? HasProperty(O,Pk)。 C。如果kPresent是 true ,那么我。让kValue成为   ?得到(O,Pk)。 II。表演?调用(callbackfn,T,«kValue,k,O»)。 d。   将k增加1。
  12.   
  13. 返回未定义
  14.