Lern-X Lern-X - 2 months ago 8
Javascript Question

Differences between for and foreach in JavaScript 5

I learned that a

for
iterates on each the array's element, even if a pointed case doesn't exist, while a
forEach
skips the unexisting cases.

Moreover, when a
for
is writen, a counter must be specified (I'm not speaking about
for...in
), while a
forEach
just uses a function iterator.

Well. Could you answer to the four following questions please ?


  1. Does really a
    forEach
    skips unexisting arrays' cases while a
    for
    doesn't ?

  2. Does a
    forEach
    uses an intern counter (we just don't have to write it) ? Or is it a totally different mechanism than a
    for
    ?

  3. In some languages, a
    forEach
    doesn't go through an array in the same order than the array's order. What about JavaScript

  4. Finally, are there other differences between them (exclusing, of course, grammatical/syntaxical ones) ?


Answer

The for keyword is a language construct, this is the fastest and most "raw" way to iterate over things. It has three styles:

  1. The C-style for: for ( initializer; condition; iterator ) { code... } - this one is the most flexible and time-tested version. To iterate over a list, you start going over all list indexes from 0 to the list's length. You can also go over every other, third etc element. Most of the time, this is good enough.

  2. The Javascript for-in for (var key in object) { code ... } - this one is a good way to go over every key in an object, for example, to output all values of a JSON object.

  3. (ES2015) The Javascript for-of: for (var item of collection) { code ... } - this one is new and available in modern browsers. It lets you skip the indexes and counters, and lets you walk over every item of a collection. (Say, every object in a products list.) It does the same thing as the C-style for, but is easier to use.

However, the forEach function is specific to Array objects in Javascript, and lets you run a function for every item in an array. It's good if you have an utility function that does all the work for you.

Here's how to use all of the above kinds of iteration:

// most plain kind of array with a length of 7
var myArray = [1, 2, 3, 4, 5, 6, undefined];
// a weird kind of array with no values between index 3 and 100
// its length is 102 
var mySparseArray = [1, 2, 3, 4];
mySparseArray[100] = 5;
mySparseArray[101] = 6;

// 1. C-style for
// ** can control how index is incremented
// ** needs an extra variable to iterate with
for (var i = 0; i < myArray.length; i += 1) {
    console.log(myArray[i]);
    // logs 1, 2, 3, 4, 5, 6, undefined
}

for (var i = 0; i < mySparseArray.length; i += 1) {
    console.log(myArray[i]); 
    // logs 1, 2, 3, 4, undefined, undefined, ... (up to index 100), 5, 6
} 

// 2. for..in
// ** keys are iterated over in non-guaranteed order
//    (you might get 2, "length", 1, 0, 3)
// ** all keys are returned, incl "length" etc
for (var key in myArray) {
    console.log(myArray[key]);
    // logs 1, 2, 3, 4, 5, 6 
}

for (var key in mySparseArray) {
    console.log(mySparseArray[key]);
    // logs 1, 2, 3, 4, 5, 6
    // this for-loop "thinks" the array is an object with numbers for keys
}

// 3. for..of
// ** only available in browsers with ES2015 support
// ** supports many other things than Arrays - TypedArrays, Iterators...
for (var item of myArray) {
    console.log(item);
}

for (var item in mySparseArray) {
    console.log(item);
    // logs 1, 2, 3, 4, undefined, undefined, ... (up to index 100), 5, 6
}

// 4. forEach
// ** calls a function for each element (considered slow)
// ** supports only Arrays (unless you call it differently)
function myCallback(element) {
  console.log(element);
}
myArray.forEach(myCallback); // logs 1, 2, 3, 4, 5, 6
mySparseArray.forEach(myCallback); // logs 1, 2, 3, 4, 5, 6

Make sure to try these out in your browser's developer console! You can see each of the above pieces of code in action.

Make sure to check out the MDN reference on iterations.