TypeError: 'x' ist nicht iterierbar
Der JavaScript-Ausnahmefehler "is not iterable" tritt auf, wenn der Wert, der in ein Array oder einen Funktionsaufruf gespreadet wird, als rechte Seite von for...of
, als Argument einer Funktion wie Promise.all
oder Set()
, oder als rechte Seite einer Array-Destrukturierungszuweisung, kein iterierbares Objekt ist. Dieser Fehler tritt auch auf, wenn Array.fromAsync()
oder for await...of
mit einem nicht-asynchronen iterierbaren verwendet wird.
Nachricht
TypeError: Spread syntax requires ...iterable[Symbol.iterator] to be a function (V8-based & Safari) TypeError: %Array%.from requires that the property of the first argument, items[Symbol.iterator], when exists, be a function (V8-based & Safari) TypeError: Array.fromAsync requires that the property of the first argument, items[Symbol.asyncIterator], when exists, be a function (V8-based & Safari) TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator)) (V8-based) TypeError: x is not async iterable (V8-based) TypeError: x is not iterable (V8-based & Firefox) TypeError: undefined is not a function (near '...y of x...') (Safari) TypeError: Array.from: no function (Safari) TypeError: Type error (Safari)
Fehlertyp
Was ist schiefgelaufen?
Der Wert, der in ein Array oder einen Funktionsaufruf gespreadet wird, als rechte Seite von for...of
, als Argument einer Funktion wie Promise.all
oder Set()
, oder als rechte Seite einer Array-Destrukturierungszuweisung, ist kein iterierbares Objekt. Ein iterierbares Objekt kann ein eingebauter iterierbarer Typ wie Array
, String
oder Map
, ein Generatorergebnis oder ein Objekt sein, das das iterierbare Protokoll implementiert.
const nonIterable1 = {};
const nonIterable2 = { [Symbol.iterator]: 1 };
[...nonIterable1];
Math.max(...nonIterable1);
for (const x of nonIterable1);
new Set(nonIterable1);
Array.from(nonIterable2);
new Int8Array(nonIterable2);
const [] = nonIterable1;
Beispiele
Array-Destrukturierung eines nicht-iterierbaren Objekts
const myObj = { arrayOrObjProp1: {}, arrayOrObjProp2: [42] };
const {
arrayOrObjProp1: [value1],
arrayOrObjProp2: [value2],
} = myObj; // TypeError: object is not iterable
console.log(value1, value2);
Das nicht-iterierbare Objekt könnte sich in einigen Laufzeitumgebungen als undefined
herausstellen.
Über die Eigenschaften eines Objekts iterieren
In JavaScript sind Object
e nicht iterierbar, es sei denn, sie implementieren das iterierbare Protokoll. Daher können Sie for...of
nicht verwenden, um über die Eigenschaften eines Objekts zu iterieren.
const obj = { France: "Paris", England: "London" };
for (const p of obj) {
// …
} // TypeError: obj is not iterable
Stattdessen müssen Sie Object.keys
oder Object.entries
verwenden, um über die Eigenschaften oder Einträge eines Objekts zu iterieren.
const obj = { France: "Paris", England: "London" };
// Iterate over the property names:
for (const country of Object.keys(obj)) {
const capital = obj[country];
console.log(country, capital);
}
for (const [country, capital] of Object.entries(obj)) {
console.log(country, capital);
}
Eine weitere Möglichkeit für diesen Anwendungsfall könnte die Verwendung eines Map
sein:
const map = new Map();
map.set("France", "Paris");
map.set("England", "London");
// Iterate over the property names:
for (const country of map.keys()) {
const capital = map.get(country);
console.log(country, capital);
}
for (const capital of map.values()) {
console.log(capital);
}
for (const [country, capital] of map.entries()) {
console.log(country, capital);
}
Über einen Generator iterieren
Generatorfunktionen sind Funktionen, die Sie aufrufen, um ein iterierbares Objekt zu erzeugen.
function* generate(a, b) {
yield a;
yield b;
}
for (const x of generate) {
console.log(x);
} // TypeError: generate is not iterable
Wenn sie nicht aufgerufen werden, ist das entsprechende Function
-Objekt für den Generator aufrufbar, aber nicht iterierbar. Der Aufruf eines Generators erzeugt ein iterierbares Objekt, das über die während der Ausführung des Generators gelieferten Werte iterieren wird.
function* generate(a, b) {
yield a;
yield b;
}
for (const x of generate(1, 2)) {
console.log(x);
}
Über ein benutzerdefiniertes iterierbares Objekt iterieren
Benutzerdefinierte iterierbare Objekte können erstellt werden, indem die Symbol.iterator
-Methode implementiert wird. Sie müssen sicherstellen, dass Ihre Iteratorfunktion ein Objekt zurückgibt, das ein Iterator ist, was bedeutet, dass es eine next-Methode haben muss.
const myEmptyIterable = {
[Symbol.iterator]() {
return []; // [] is iterable, but it is not an iterator — it has no next method.
},
};
Array.from(myEmptyIterable); // TypeError: myEmptyIterable is not iterable
Hier ist eine korrekte Implementierung:
const myEmptyIterable = {
[Symbol.iterator]() {
return [][Symbol.iterator]();
},
};
Array.from(myEmptyIterable); // []