TypeError: 'x' is not iterable
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-Destrukturierung angegeben wird, kein iterierbares Objekt ist. Dieser Fehler tritt auch auf, wenn Array.fromAsync() oder for await...of mit einem nicht-async 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
TypeError
Was ist schiefgelaufen?
Der Wert, der in ein Array oder einen Funktionsaufruf gespreadet wird, als rechte Seite von for...of, oder als Argument einer Funktion wie Promise.all oder Set(), oder als Quelle eines Array-Destrukturierungsmusters, ist kein iterierbares Objekt. Ein iterierbares Objekt kann ein eingebauter iterierbarer Typ sein wie Array, String oder Map, ein Generatorergebnis, oder ein Objekt, 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);
In einigen Laufzeitumgebungen könnte das nicht iterierbare Objekt undefined sein.
Iteration über Eigenschaften eines Objekts
In JavaScript sind Objecte nicht iterierbar, es sei denn, sie implementieren das iterierbare Protokoll. Aus diesem Grund 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);
}
Iteration über einen Generator
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 des Generators aufrufbar, aber nicht iterierbar. Das Aufrufen eines Generators erzeugt ein iterierbares Objekt, das über die während der Ausführung des Generators zurückgegebenen Werte iterieren wird.
function* generate(a, b) {
yield a;
yield b;
}
for (const x of generate(1, 2)) {
console.log(x);
}
Iteration über ein benutzerdefiniertes iterierbares Objekt
Benutzerdefinierte iterierbare Objekte können erstellt werden, indem die Methode Symbol.iterator implementiert wird. Sie müssen sicherstellen, dass Ihre Iteratormethode 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); // []