Javascript Arrays forEach ()

forEach Arrays durchlaufen

forEach() ist eine Variante des klassischen for-Loops. forEach ruft eine Callback-Funktion für jedes Element des Arrays auf und ist intuitiver als die klassische for-i-Iteration.

18-12-15 SITEMAP

forEach() callback

Eine klassische for-Anweisung in Javascript basiert auf einer Variablen für den Index und führt Anweisungen in abgezählten Schritten durch (Interation), bis eine Bedingung nicht mehr zutrifft. Da Arrays ebenfalls auf einem Index basieren, sind for-Iterationen für Arrays wie geschaffen.

const books = [
	{ autor: 'Jane Austen' },
	{ autor: 'Jared Diamond'},
	{ autor: 'Dorothy L. Sayers'}
]

Wie bei vielen Javascript-Methoden gibt mehrere Optionen:

Klassischer for-Loop
for (let i=0; i<books.length; i++) {
  console.log(`i:${i} | Autor:`, books[i]);
}
Aufruf der Callback-Funktion
books.forEach (autoren);

function autoren (item) {
	console.log ("Favorit " + item.autor)
}
Callbackfunktion im foreach
books.forEach ((book, index) => {
  console.log(`i:${index} | Autor:`, book);
});
Callbackfunktion als Arrow-Funktion
books.forEach (function (book, index) {
  console.log(`i:${index} | Autor:`, book);
});

Vier Wege, ein Ergebnis

Das Ergebnis ist in allen Variationen dasselbe, aber beim forEach sind weniger Informationen erforderlich: Die Größe des Arrays muss nicht angegeben werden, kein Startpunkt und keine Schrittweite.

Und ein weiterer Punkt für forEach: Die Callback-Funktion verschließt die Variable im Scope des forEach. Würde eine Variable außerhalb definiert und innerhalb von forEach benutzt, würde die Variable außerhalb davon nicht berührt und ihren Wert behalten.

[Log] i : 0 | Autor: – {autor: "Jane Austen"} (foreach.html, line 164)
[Log] i : 1 | Autor: – {autor: "Jared Diamond"} (foreach.html, line 164)
[Log] i : 2 | Autor: – {autor: "Dorothy L. Sayers"} (foreach.html, line 164)

forEach ruft für jedes Element des Arrays eine Callback-Funktion auf und übergibt der Callback-Funktion den Wert des Arrays. Die Callback-Funktion (book, index) => {…} sorgt auch dafür, dass alle Variablen innerhalb des forEach-Scopes bleiben.

Wenn die Aktionen auf dem Array umfangreicher werden, gibt es eine weitere Schreibweise für den Einsatz von forEach:

function autorlist (autor, index) {
	console.log (index + ' ' + books[index].autor);
}
books.forEach (autorlist);
                   ^
                   |
            callback-Funktion 

books.slice(2, 5).forEach(autorlist);

forEach ist einfacher, wenn wir das Array vollständig durchlaufen wollen. Soll nur ein Teil des Arrays behandelt werden, kommt z.B. array.slice zum Einsatz.

forEach mit nodeLists

Auch wenn forEach dem eleganten each aus jQuery sehr ähnlich sieht – forEach mit querySelectorAll hat zum großen Leidwesen aller for i-Genervten lange Zeit nicht funktioniert:

document.querySelectorAll('h3').forEach (buildIndex);

querySelectorAll sammelt und filtert HTML-Elemente, aber gibt kein Array zurück, sondern eine NodeList. Eine NodeList sieht aus wie ein Array, aber ihr haben bis ECMAScript 2015 viele Methoden von Arrays gefehlt, darunter auch forEach.

Jetzt unterstützen alle modernen Browser forEach auch auf bei NodeLists.

forEach Bild Donut forEach Bild Toast forEach Bild Melone
Dieser Browser hat forEach mit NodeLists nicht auf dem Schirm
const elements = document.querySelectorAll("img");

elements.forEach(function(img, index) {
   console.log( img.getAttribute("alt") );
});

Allerdings bleibt IE11 (Release 2013!) beim forEach mit NodeList weiterhin außen vor. Damit auch IE11 forEach mit NodeLists abarbeitet, gibts ein Polyfill.

if (window.NodeList && !NodeList.prototype.forEach) {
   console.info("forEach Polyfill für IE11");
   NodeList.prototype.forEach = function (callback, thisArg) {
      thisArg = thisArg || window;
      for (var i = 0; i < this.length; i++) {
         callback.call(thisArg, this[i], i, this);
      }
   };
}

Quelle: bob-lee / polyfill-ie11-nodelist-foreach.js

Die Eigenschaft prototype fügt einem Javascript-Objekt neue Eigenschaften und Methoden hinzu. Javascript Polyfills nutzen Prototyping, um alten Browsern neue Eigenschaften und Methoden beizubringen.

forEach in Arrow Function

Und da wir gerade bei IE und forEach sind: Es gibt auch die kompakte Schreibweise mit dem Pfeil, die Arrow-Funktion. Ein Blick ins Ofenrohr des Internets: Die Arrow Function geht IE11 ebenfalls gegen den Strich.

elements.forEach (img => console.log (img.getAttribute("alt")));

querySelectorAll gibt eine NodeList zurück, getElementsByClassName, –ByName und -TagName geben eine HTML Collection zurück. forEach auf HTMLCollection gibts nicht.

Der klassische for-Loop

Der altgediente for-Loop hat weiterhin seine Darseinsberechtigung bei numerischen Arrays: Die Reihenfolge ist garantiert, for kann rückwärts laufen.

Zugunsten des for-Loops kann man anführen, dass for (let i) über alles läuft: Über Arrays, über HTML Collections (z.B. aus getElementsByName) und über Nodelists (aus querySelectorAll).

Und zuguterletzt unterbricht ein break den for (let i)-Look vorzeitig aufgrund einer Bedingung.

for (let j=0; j<divs.length; j++) {
	divs[j].textContent = j;
	if (j == index) break;
}