Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten. Erfahre mehr über dieses Experiment.

View in English Always switch to English

TypeError: Reduce von leerem Array ohne Ausgangswert

Der JavaScript-Ausnahmefehler "reduce of empty array with no initial value" tritt auf, wenn eine reduce-Funktion verwendet wird.

Nachricht

TypeError: Reduce of empty array with no initial value (V8-based & Firefox & Safari)

Fehlertyp

TypeError

Was ist schiefgelaufen?

In JavaScript gibt es mehrere reduce-Funktionen:

Diese Funktionen nehmen optional einen initialValue an (der als erstes Argument für den ersten Aufruf des callback verwendet wird). Wenn jedoch kein Anfangswert bereitgestellt wird, wird das erste Element des Array oder TypedArray als Anfangswert verwendet. Dieser Fehler tritt auf, wenn ein leeres Array übergeben wird, da in diesem Fall kein Anfangswert zurückgegeben werden kann.

Beispiele

Ungültige Fälle

Dieses Problem tritt häufig in Kombination mit einem Filter auf (Array.prototype.filter(), TypedArray.prototype.filter()), der alle Elemente der Liste entfernt. Dadurch bleibt kein Element übrig, das als Anfangswert verwendet werden könnte.

js
const ints = [0, -1, -2, -3, -4, -5];
ints
  .filter((x) => x > 0) // removes all elements
  .reduce((x, y) => x + y); // no more elements to use for the initial value.

Ähnlich kann das gleiche Problem auftreten, wenn ein Tippfehler in einem Selektor vorliegt oder eine unerwartete Anzahl von Elementen in einer Liste vorhanden ist:

js
const names = document.getElementsByClassName("names");
const name_list = Array.prototype.reduce.call(
  names,
  (acc, name) => `${acc}, ${name}`,
);

Gültige Fälle

Diese Probleme können auf zwei verschiedene Arten gelöst werden.

Eine Möglichkeit besteht darin, tatsächlich einen initialValue als neutrales Element des Operators bereitzustellen, wie 0 für die Addition, 1 für eine Multiplikation oder einen leeren String für eine Verkettung.

js
const ints = [0, -1, -2, -3, -4, -5];
ints
  .filter((x) => x > 0) // removes all elements
  .reduce((x, y) => x + y, 0); // the initial value is the neutral element of the addition

Eine andere Möglichkeit wäre, den leeren Fall entweder vor dem Aufruf von reduce zu behandeln oder im Callback, nachdem ein unerwarteter Dummy-Anfangswert hinzugefügt wurde.

js
const names = document.getElementsByClassName("names");

let nameList1 = "";
if (names.length >= 1) {
  nameList1 = Array.prototype.reduce.call(
    names,
    (acc, name) => `${acc}, ${name}`,
  );
}
// nameList1 === "" when names is empty.

const nameList2 = Array.prototype.reduce.call(
  names,
  (acc, name) => {
    if (acc === "")
      // initial value
      return name;
    return `${acc}, ${name}`;
  },
  "",
);
// nameList2 === "" when names is empty.

Siehe auch