是否保证foreach每次都在同一数据集上以相同的顺序循环?

时间:2018-11-29 19:51:17

标签: javascript loops foreach iteration sequence

是否保证foreach(Array.prototype.forEach)每次都在相同数据集上以相同顺序循环?为什么呢?

2 个答案:

答案 0 :(得分:1)

如果实现遵循标准,则是,forEach按顺序处理数组,但稀疏数组除外,在稀疏数组中会忽略未初始化的值。 the spec中描述了forEach()

  

forEach为数组中存在的每个元素按升序调用一次callbackfn。仅对实际存在的数组元素调用callbackfn。不会因为缺少数组元素而调用它。

它从以下位置开始遍历索引:

  

让lenValue是使用参数“ length”调用O的[[Get]]内部方法的结果   设k为0。
  重复,而k   ...
  将k增加1

在javascript数组中是对象,它们具有length属性和作为索引的整数键。规范说它将从k=0开始,并以arr[k]的升序调用k < length。它将为arr具有属性k

的所有值调用回调

forEach忽略元素的稀疏数组的示例可能如下所示:

let a  = Array(10)
a[5] = "Five"
a[9] = "Nine"
console.log(a)
// ignores initialized values:
a.forEach((item) => console.log(item))

如果您在回调内部执行异步操作,则可能看起来回调没有按顺序进行,但仍然按顺序进行。

基于评论的编辑:

您可以通过一点黑客操作将看起来像数组的对象传递给forEach(它具有长度和整数键)。 forEach将按照 index 的顺序调用项目,而不是在对象上定义的顺序。例如:

// an object that has enough info
// for forEach to use
let o = {
    3: "three",
    2: "two",
    0: "zero",
    1: "one",

    length: 4
}

// calls in order of indexes, not order keys were defined
Array.prototype.forEach.call( o, (i) => console.log(i))

答案 1 :(得分:1)

是的,forEach将等待上一项完成,然后再处理下一项

//Sync methods;
[1,2,3].forEach(function(e){
    console.log(e)
});
//Output:
//1
//2
//3

如果您在循环内使用 Async方法,则会依次调用它们,但循环将不等待回调。

//Async Methods
[1,2,3].forEach(function(e){
    someAsyncMethod(e, console.log);
});
//Output example:
//3
//1
//2

answer有一些方法可以在foreach中使用异步函数。

关于为什么的问题,有一个名为 ECMAScript 的国际标准,所有JavaScript实现都应遵循该标准; Array.prototype.forEach()的行为已在此标准中指定。

您可以在ECMAScript® 2018 Language Specification处找到Array.prototype.forEach()的规范和伪代码