MDN wants to learn about developers like you: https://qsurvey.mozilla.com/s3/MDN-dev-survey

Die forEach()-Methode führt eine übergebene Funktion für jedes Element eines Arrays aus.

var a = ['a', 'b', 'c'];

a.forEach(function(element) {
    console.log(element);
});

// a
// b
// c

Syntax

arr.forEach(function callback(currentValue, index, array) {
    //your iterator
}[, thisArg]);

Parameter

callback
Funktion, die ein Element aus dem Array überarbeitet. Sie bekommt ihrerseits drei Parameter übergeben:
currentValue
Das zu bearbeitende Element aus dem Array.
index
Der Index des aktuellen Elements im Array.
array
Das gesamte Array.
thisArg Optional
Wert, der bei der Ausführung der callback-Funktion als this genutzt wird.

Rückgabewert

undefined.

Beschreibung

forEach() führt die übergebene callback-Funktion an jedem Element des ausführenden Arrays in aufsteigender Reihenfolge durch. Sie überspringt dabei gelöschte und ausgeschlossene Elemente. Sie wird allerdings für Elemente mit dem Wert undefined ausgeführt.

callback wird mit drei Argumenten aufgerufen:

  • Dem Wert des Elements (value)
  • Dem Index des Elements (index)
  • Das Array, das durchlaufen wird (array)

Wenn ein thisArg-Parameter an forEach() übergeben wird, wird er auch an die callback-Funktion als deren this-Wert weitergegeben.  Andernfalls wird dafür undefined genutzt.  Der this-Wert, der in der callback-Funktion wahrgenommen wird, ist festgelegt durch die generellen Regeln für die Nutzung von this in einer Funktion.

Die Reichweite der Elemente, die von forEach() durchlaufen werden, wird vor dem ersten Aufruf der callback-Funktion ermittelt. Elemente, die danach an das Array angefügt werden, werden nicht von der callback-Funktion beachtet. Wenn sich der Wert eines vorhandenen Elements im Array ändert, ist der Wert, der an die callback-Funktion übergeben wird, derjenige, den das Element zum Zeitpunkt des Aufrufs von forEach() innehatte; Elemente, die zuvor gelöscht wurden, werden nicht beachtet. Wenn Elemente, die bereits durchlaufen wurden, während des Durchlaufs gelöscht werden (z. B. durch shift()), werden Folgeelemente übersprungen - siehe Beispiel unten.

forEach() führt die callback-Funktion einmal für jedes Array-Element aus; im Gegensatz zu map() oder reduce() gibt es immer den Wert undefined zurück und ist nicht verknüpfbar. Im typischen Fall werden Zusatzeffekte am Ende einer solchen Kette ausgeführt.

Hinweis: Es gibt keine Möglichkeit eine forEach()-Schleife zu unterbrechen oder verlassen, außer durch eine Fehlermeldung. Falls dies trotzdem gewünscht ist, stellt forEach() das falsche Mittel dar. Stattdessen solle in solchen Fällen eine einfache Schleife benutzt werden. Wenn die Array-Elemente auf ein bestimmtes Ergebnis getestet werden und die Rückgabe eines Boolean nötig ist, kann every() oder some() benutzt werden. Falls verfügbar können auch die neuen Methoden find() und findIndex() für vorzeitige Abbrüche bei passenden Stellen benutzt werden.

Beispiele

Von for nach forEach konvertieren

vorher

var items = ['item1', 'item2', 'item3'];
var copy = [];

for (var i=0; i<items.length; i++) {
  copy.push(items[i])
}

nachher

var items = ['item1', 'item2', 'item3'];
var copy = [];

items.forEach(function(item){
  copy.push(item)
});

 

Ausgeben der Inhalte eines Arrays

Der folgende Quelltext gibt eine Zeile für jedes Element eines Arrays aus:

function logArrayElements(element, index, array) {
  console.log('a[' + index + '] = ' + element);
}

// Hinweis zur Auslassung: Es gibt keinen Eintrag mit dem Index 2, somit wird dieser übersprungen
[2, 5, , 9].forEach(logArrayElements);
// Ausgabe:
// a[0] = 2
// a[1] = 5
// a[3] = 9

 

Die Schleife verlassen

Der folgende Quelltext benutzt Array.prototype.every um den Inhalt eines Arrays auszugeben und stoppt wenn ein Wert erreicht ist, also den THRESHOLD überschreitet.

var THRESHOLD = 12;
var v = [5, 2, 16, 4, 3, 18, 20];
var res;

res = v.every(function(element, index, array) {
  console.log('element:', element);
  if (element >= THRESHOLD) {
    return false;
  }

  return true;
});
console.log('res:', res);
// Ausgabe:
// element: 5
// element: 2
// element: 16
// res: false

res = v.some(function(element, index, array) {
  console.log('element:', element);
  if (element >= THRESHOLD) {
    return true;
  }

  return false;
});
console.log('res:', res);
// Ausgabe:
// element: 5
// element: 2
// element: 16
// res: true

 

thisArg benutzen

Das folgende (fingierte) Beispiel aktualisiert eine Objekteigenschaft eines jeden Array-Eintrags:

function Counter() {
  this.sum = 0;
  this.count = 0;
}
Counter.prototype.add = function(array) {
  array.forEach(function(entry) {
    this.sum += entry;
    ++this.count;
  }, this);
  // ^---- Beachten
};

var obj = new Counter();
obj.add([2, 5, 9]);
obj.count;
// 3 
obj.sum;
// 16

Da der thisArg-Parameter (this) forEach() zur Verfügung steht, wird er an callback weitergegeben jedesmal, wenn es aufgerufen wird, um es als seinen this-Wert zu benutzen.

Wenn das Funktionsargument durch einen arrow-Funktionsausdruck gegeben wird, kann der thisArg-Parameter ausgelassen werden, da arrow-Funktionen lexikalisch den this-Wert vermerken.

 

Funktion zum Kopieren eines Objekts

Der folgende Quelltext erzeugt eine Kopie des übergebenen Objekts. Es gibt verschiedene Möglichkeiten, ein Objekt zu kopieren. Die Folgende ist nur eine davon und dient zur Veranschaulichung, wie Array.prototype.forEach() funktioniert, indem die ECMAScript 5 Object.*-Funktionen genutzt werden.

function copy(o) {
  var copy = Object.create(Object.getPrototypeOf(o));
  var propNames = Object.getOwnPropertyNames(o);

  propNames.forEach(function(name) {
    var desc = Object.getOwnPropertyDescriptor(o, name);
    Object.defineProperty(copy, name, desc);
  });

  return copy;
}

var o1 = { a: 1, b: 2 };
var o2 = copy(o1); // o2 sieht jetzt aus wie o1

 

Wird das Array während des Durchlaufes modifiziert, könnten andere Elemente übersprungen werden.

Das folgende Beispiel loggt "eins", "zwei", "vier". Wenn der Eintrag mit dem Wert "zwei" erreicht ist, wird der erste Eintrag des Arrays entfernt (shift), was dazu führt, dass alle übrigen Einträge um eine Position aufrücken. Weil Element "vier" jetzt an einer früheren Position im Array ist, wird "drei" übersprungen. forEach() erzeugt keine Kopie des Arrays vor dem Durchlauf.

var words = ['eins', 'zwei', 'drei', 'vier'];
words.forEach(function(word) {
  console.log(word);
  if (word === 'zwei') {
    words.shift();
  }
});
// eins
// zwei
// vier

Polyfill

forEach() wurde in der 5. Edition zum ECMA-262 Standard hinzugefügt; somit muss es nicht in anderen Ausführungen dieses Standards vorhanden sein. Man kann es umgehen, indem man den nachfolgenden Quelltext an den Anfang des Skriptes einfügt, was die Benutzung von forEach() auch in Ausführungen, die es nicht von vornherein unterstützen, ermöglicht.  Dieser Algorithmus ist genau der, der in ECMA-262, 5. Edition spezifiziert wurde, in der Annahme, dass Object und TypeError ihre ursprünglichen Werte haben und dass callback.call() auf dieselbe Weise funktioniert wie Function.prototype.call.

// Production steps of ECMA-262, Edition 5, 15.4.4.18
// Reference: http://es5.github.io/#x15.4.4.18
if (!Array.prototype.forEach) {

  Array.prototype.forEach = function(callback, thisArg) {

    var T, k;

    if (this === null) {
      throw new TypeError(' this is null or not defined');
    }

    // 1. Let O be the result of calling ToObject passing the |this| value as the argument.
    var O = Object(this);

    // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
    // 3. Let len be ToUint32(lenValue).
    var len = O.length >>> 0;

    // 4. If IsCallable(callback) is false, throw a TypeError exception.
    // See: http://es5.github.com/#x9.11
    if (typeof callback !== "function") {
      throw new TypeError(callback + ' is not a function');
    }

    // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
    if (arguments.length > 1) {
      T = thisArg;
    }

    // 6. Let k be 0
    k = 0;

    // 7. Repeat, while k < len
    while (k < len) {

      var kValue;

      // a. Let Pk be ToString(k).
      //   This is implicit for LHS operands of the in operator
      // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
      //   This step can be combined with c
      // c. If kPresent is true, then
      if (k in O) {

        // i. Let kValue be the result of calling the Get internal method of O with argument Pk.
        kValue = O[k];

        // ii. Call the Call internal method of callback with T as the this value and
        // argument list containing kValue, k, and O.
        callback.call(T, kValue, k, O);
      }
      // d. Increase k by 1.
      k++;
    }
    // 8. return undefined
  };
}

Spezifikationen

Spezifikation Status Kommentar
ECMAScript 5.1 (ECMA-262)
Die Definition von 'Array.prototype.forEach' in dieser Spezifikation.
Standard Initiale Definition. Implementiert in JavaScript 1.6.
ECMAScript 2015 (6th Edition, ECMA-262)
Die Definition von 'Array.prototype.forEach' in dieser Spezifikation.
Standard  
ECMAScript Latest Draft (ECMA-262)
Die Definition von 'Array.prototype.forEach' in dieser Spezifikation.
Lebender Standard  

Browser-Kompatibilität

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support (Ja) 1.5 (1.8) 9 (Ja) (Ja)
Feature Android Chrome für Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support (Ja) (Ja) 1.0 (1.8) (Ja) (Ja) (Ja)

Siehe auch

Schlagwörter des Dokuments und Mitwirkende

 Mitwirkende an dieser Seite: Martin.Kraft, posoppis, StevenS77, L15t3, schlagi123, langco, sudave, olastor
 Zuletzt aktualisiert von: Martin.Kraft,