There are multiple ways to loop through an Array in JavaScript, and often you can’t tell their nuances from the applicable scenarios. This paper will sort out the advantages and disadvantages of each of them in detail and organize them into a table for comparison.

cycle Accessibility element Access to the index Can be iterative property Support the interrupt Support to await Start at any location is supported
for Square root Square root x Square root Square root Square root
for in Square root x Square root Square root Square root x
forEach Square root Square root x x x x
for of Square root Square root x Square root Square root x

The sample address

For (ES1)

This loop has a long history and has been supported since ECMAScript 1.

const arr = ['a'.'b'.'c'];
arr.prop = 'property value';

for (let index=0; index < arr.length; index++) {
  const elem = arr[index];
  console.log(index, elem);
}

// Output:
// 0, 'a'
// 1, 'b'
// 2, 'c'
Copy the code

The for loop is generic, iterating through the element and the current element index, but it is syntactically verbose.

for in (ES1)

The history of for in is as old as for.

const arr = ['a'.'b'.'c'];
arr.prop = 'property value';

for (const key in arr) {
  console.log(key);
}

// Output:
/ / '0'
/ / '1'
/ / '2'
// 'prop'
Copy the code

For in is not a good choice for looping arrays.

  • Iterate over the property key, not the value
  • Because of the propertieskeyIs a string, and the iterated element index isstring, notnumber.
  • Iterate over all enumerable property keys on an array instance, not the elements in the array.

If you want to get all of an Object’s enumerable properties (including those on the prototype chain), then for in will do the job. If it is only the declared properties of the Object itself, then Object.keys is more suitable.

forEach (ES5)

Since neither for nor for-in are particularly suited to looping over Arrays, ECMAScript 5 introduced the helper method Array.prototype.foreach.

const arr = ['a'.'b'.'c'];
arr.prop = 'property value';

arr.forEach((elem, index) = > {
  console.log(elem, index);
});

// Output:
// 'a', 0
// 'b', 1
// 'c', 2
Copy the code

This method is handy because it allows us to access array elements and their subscripts without having to do too much. Arrow functions (introduced in ES6) make this approach syntactically more elegant.

ForEach mainly determined that:

  • Not supported inside the loopawaitOperation.
  • Even if you find the element you want, you can’t break the loop.

To implement the interrupt loop, use the array.prototype.same method introduced at the same time. Some loops through all Array elements and stops when its callback returns a true value.

const arr = ['red'.'green'.'blue'];
arr.some((elem, index) = > {
  if (index >= 2) {
    return true; // End the loop
  }
  console.log(elem);
  // returns undefined implicitly, continuing the loop
});

// Output:
// 'red'
// 'green'
Copy the code

for of (ES6)

For of is a new syntax introduced in ECMAScript 6.

const arr = ['a'.'b'.'c'];
arr.prop = 'property value';

for (const elem of arr) {
  console.log(elem);
}
// Output:
// 'a'
// 'b'
// 'c'
Copy the code

For of is suitable for traversing numbers:

  • Iterate over all array elements
  • Internal supportawaitAnd evenES2018The introduction of thefor-await-ofgrammar
  • You can use break and continue to break out of the loop

Another benefit of for-of is that we can iterate not only over a set of numbers, but over any iterable (such as a Map)

const myMap = new Map()
  .set(false.'no')
  .set(true.'yes');for (const [key, value] of myMap) {
  console.log(key, value);
}

// Output:
// false, 'no'
// true, 'yes'
Copy the code

Traversing myMap produces [key, value] pairs that can be deconstructed to facilitate direct access.

If you need to be aware of the current element index in a loop, you can use the Array method entries to return iterable [index, value] pairs. The same deconstruction as map accesses index and value directly:

const arr = ['chocolate'.'vanilla'.'strawberry'];

for (const [index, value] of arr.entries()) {
  console.log(index, value);
}
// Output:
// 0, 'chocolate'
// 1, 'vanilla'
// 2, 'strawberry'
Copy the code

Await test in the circulating body

Prepare the following code to test await in the loop and getFruit to simulate a remote service delayed return.

const fruits = ["apple"."grape"."pear"];

const sleep = (ms) = > {
  return new Promise((resolve) = > setTimeout(resolve, ms));
};

const getFruit = (fruit) = > {
  return sleep(2000).then((v) = > fruit);
};
Copy the code

If you look at for of, the elements are printed at expected intervals.

(async function(){
    console.log('start');
    for (fruit of fruits) {
        const element = await getFruit(fruit);
        console.log(element);
    }
    console.log('start'); }) ();//3 elements output 2s apart
"start"
"apple"
"grape"
"pear"
"end"
Copy the code

ForEach = forEach = forEach = forEach = forEach = forEach = forEach = forEach = forEach = forEach

(async function () {

  console.log("foreach loop start ....");
  fruits.forEach(async value => {
    const element = await getFruit(value);
    console.log(element);
  });
  console.log("foreach loop end ...."); }) ();// Simultaneously output
foreach loop start ....
foreach loop end ....
// Output the following three at the same time after 2s interval
apple
grape
pear
Copy the code

The sample address