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

callbackfn should be a function that accepts three arguments. forEach calls callbackfn once for each element present in the array, in ascending order. callbackfn is called only for elements of the array which actually exist; it is not called for missing elements of the array.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callbackfn. If it is not provided, undefined is used instead.

callbackfn is called with three arguments: the value of the element, the index of the element, and the object being traversed.

forEach does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn.

The range of elements processed by forEach is set before the first call to callbackfn. Elements which are appended to the array after the call to forEach begins will not be visited by callbackfn. If existing elements of the array are changed, their value as passed to callback will be the value at the time forEach visits them; elements that are deleted after the call to forEach begins and before being visited are not visited.

When the forEach method is called with one or two arguments, the following steps are taken:

  1. Let O be the result of calling ToObject passing the this value as the argument.
  2. Let lenValue be the result of calling the [[Get]] internal method of O with the argument "length".
  3. Let len be ToUint32(lenValue).
  4. If IsCallable(callbackfn) is false, throw a TypeError exception.
  5. If thisArg was supplied, let T be thisArg; else let T be undefined.
  6. Let k be 0.
  7. Repeat, while k < lenLet Pk be ToString(k).Let kPresent be the result of calling the [[HasProperty]] internal method of O with argument Pk.If kPresent is true, thenLet kValue be the result of calling the [[Get]] internal method of O with argument Pk.Call the [[Call]] internal method of callbackfn with T as the this value and argument list containing kValue, k, and O.Increase k by 1.
  8. Return undefined.

The length property of the forEach method is 1.

NOTEThe forEach function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method. Whether the forEach function can be applied successfully to a host object is implementation-dependent.

forEach prototype* method, introduced in ES5, executes a provided callback function (a function passed to another function as an argument) once for each value in Array, Map (made up of key-value pairs), Set, NodeList (an array-like object often returned by Document.querySelectorAll()), or HTMLCollection (an array-like object often returned by Document.getElementsByClassName()) objects, in ascending order.

There are some little differences between forEach and for ... of for ... in,

  1. You cannot stop a for Each
  2. The callback is none-blocking, which means if you use async/await all the items in forEach will be send out at the same time.

for ... in actually iterates through the enumerable properties of an object/array. That means the properties that exist in the array, so the X that goes in object[X] or array[X]. For arrays, that’s the index. For objects, they’re the keys (not the values). The for-in loop actually is applicable over all those which have some enumerable properties [Enumerable properties are those properties whose internal [[Enumerable]] flag is set to true, which is the default for properties created via simple assignment or via a property initializer ]. In normal usage, the for-in loop is basically used to carve out the properties of an object. Let us understand with an example:

for...of iterates on the other side of iterables: so instead of iterating through the keys it iterates through the values.


const list = [1, 2, 3, 4, 5, 6, 7, 8]
for(let i in list) {
    console.log(typeof i);
}

const result = [];
const request = function(num) {
    return new Promise(resolve => {
        setTimeout(() => {
            console.log(num);
            console.log(new Date());
            resolve(new Date());
        }, 1000);
    });
}

list.forEach(async (item) => {
    result.push(await request(item));
    console.log(result);
})

async function test() {
    for(let item of list) {
        result.push(await request(item));
    }
    // console.log(result);
}