Javascript Arrays forEach ()

forEach Arrays durchlaufen

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'}
]
for (let i=0; i<books.length; i++) {
	console.log(`i : ${i} | Autor:`, books[i]);
}
books.forEach ((book, index) => {
	console.log(`i : ${index} | Autor:`, book);
});
    /** oder  **/ 
books.forEach (function (book, index) {
	console.log(`i : ${index} | Autor:`, book);
});

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

[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;
}