Iterator.concat()
Baseline
2026
Neu verfügbar
Seit März 2026 funktioniert diese Funktion auf aktuellen Geräten und in aktuellen Browserversionen. Auf älteren Geräten oder in älteren Browsern funktioniert sie möglicherweise nicht.
Die statische Methode Iterator.concat() erzeugt ein neues Iterator-Objekt aus einer Liste von iterierbaren Objekten. Der neue Iterator liefert die Werte aus jeder der Eingabe-Iterables sequenziell.
Syntax
Iterator.concat(it)
Iterator.concat(it1, it2)
Iterator.concat(it1, it2, /* …, */ itN)
Parameter
it1,it2, …,itN-
Ein Objekt, das das iterable-Protokoll implementiert. Iterators, die nicht auch iterable sind, können nicht direkt an diese Methode übergeben werden; sie müssen zuerst mit
Iterator.from()umwickelt werden.
Rückgabewert
Ein neues Iterator-Objekt, das die Werte aus jeder der Eingabe-Iterables sequenziell liefert.
Beschreibung
Die Methode Iterator.concat() ist konzeptionell ähnlich zur Array-Methode concat(), aber sie funktioniert mit jeder Art von Iterable und gibt einen Iterator anstelle eines Array zurück. Das bedeutet, dass die Iterables verzögert iteriert werden können, um unnötige Allokationen oder Berechnungen zu vermeiden. Es bedeutet auch, dass Sie technisch gesehen unendliche Iterables verketten können, aber die Ergebnisse von Iterables nach dem ersten unendlichen Iterable werden niemals erreicht.
Während jedes Iterable unendlich sein kann, muss die Liste der Iterables endlich und ziemlich begrenzt in der Anzahl sein, da die Engines sehr niedrige Limits für die Anzahl der Funktionsargumente setzen. Wenn Sie eine große — oder sogar unendliche — Anzahl von Iterables verketten müssen, verwenden Sie stattdessen Iterator.prototype.flatMap().
function* infiniteIterables() {
for (let i = 1; ; i++) {
yield Array(i).fill(i);
}
}
// BAD:
// Iterator.concat(...infiniteIterables());
// The spread operator never finishes
// GOOD:
const it = infiniteIterables().flatMap((x) => x);
// Infinite sequence of numbers: 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, ...
Die Iterator.concat()-Methode ist funktional ähnlich der folgenden Funktion, die den yield*-Operator verwendet, um Werte aus jeder der Eingabe-Iterables sequenziell zu liefern:
function* concat(...iterables) {
for (const iterable of iterables) {
yield* iterable;
}
}
Wie yield* unterstützt Iterator.concat() keine Argumente, die nicht iterierbar sind (d.h. die nicht die [Symbol.iterator]()-Methode haben). Dies liegt daran, dass Iterator.concat() immer die Kontrolle über seine Iteratoren übernimmt und offene Iteratoren schließt, wenn die Methode beendet wird. Mit iterierbaren Argumenten erwirbt Iterator.concat() Iteratoren nacheinander und schließt einfach den aktuellen Iterator, wenn die Iteration gestoppt wird. Bei Iterator-Argumenten ist nicht klar, ob der Anrufer oder Iterator.concat() für das Schließen der Iteratoren verantwortlich sein soll, insbesondere für die, die Iterator.concat() nicht erreicht hat, daher erlaubt die Methode einfach keine nicht-iterierbaren Argumente.
Beispiele
>Kombinieren von Maps
In diesem Beispiel erstellen wir eine neue Map, die die Vereinigung von drei anderen Maps ist. Der Konstruktor Map() akzeptiert ein Iterable von Schlüssel-Wert-Paaren, während der Map-Iterator Schlüssel-Wert-Paare aus der Map liefert, so dass es ausreicht, Iterator.concat() auf die Maps anzuwenden, um die neue Map zu erstellen.
const map1 = new Map([
["a", 1],
["b", 2],
]);
const map2 = new Map([
["c", 3],
["d", 4],
]);
const map3 = new Map([
["a", 5],
["e", 6],
]);
const map = new Map(Iterator.concat(map1, map2, map3));
console.log(map);
// Map(5) {'a' => 5, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 6}
Beachten Sie, dass der Wert des Schlüssels "a" in der resultierenden Map 5 ist. Das liegt daran, dass der Map-Konstruktor den letzten Wert für jeden Schlüssel verwendet.
Verkettung unendlicher Iterables
Wenn eines der Eingabe-Iterables unendlich ist, wird auch der resultierende Iterator unendlich sein. Das stellt nicht sofort ein Problem dar, da Iteratoren verzögert konsumiert und jederzeit geschlossen werden können, aber es bedeutet, dass Iterables nach dem ersten unendlichen Iterable niemals erreicht werden.
function* it1() {
yield 1;
yield 2;
}
function* it2() {
let i = 3;
while (true) {
yield i++;
}
}
function* it3() {
yield "done";
}
const it = Iterator.concat(it1(), it2(), it3());
for (const value of it.take(10)) {
console.log(value); // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
}
// "done" is never reached
Verkettung von Iterables unterschiedlicher Typen
Sie können Iterables unterschiedlicher Typen verketten.
const array = [1, 2, 3];
const set = new Set([4, 5, 6]);
function* gen() {
yield 7;
yield 8;
yield 9;
}
const it = Iterator.concat(array, set, gen());
console.log([...it]); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
Die Elemente jedes Iterables können auch unterschiedliche Typen haben, genau wie Arrays.
const array = [1, "two", 3];
const set = new Set([true, {}]);
const it = Iterator.concat(array, set);
console.log([...it]); // [1, "two", 3, true, {}]
Verkettung nicht-iterierbarer Objekte
Nicht-iterierbare Objekte lösen einen TypeError aus, wenn sie an Iterator.concat() übergeben werden, weil sie nicht die [Symbol.iterator]()-Methode haben.
const nonIterable = {
next() {
return { done: true };
},
};
const it = Iterator.concat(nonIterable); // TypeError: object is not iterable
Da alle eingebauten Iteratoren die Iterator-Klasse erweitern, sind sie alle iterierbar und können an Iterator.concat() übergeben werden.
const arrayIterator = [1, 2, 3][Symbol.iterator]();
const it = Iterator.concat(arrayIterator); // No error
Um einen Iterator zu übergeben, der nicht auch iterierbar ist, können Sie ihn mit Iterator.from() umwickeln.
const nonIterable = {
next() {
return { done: true };
},
};
const it = Iterator.concat(Iterator.from(nonIterable)); // No error
Eine weitere Option ist die Verwendung von Iterator.prototype.flatMap(), das automatisch Iterator.from() aufruft. Aber seien Sie vorsichtig: Sie müssen flatMap() auf einem Iterator aufrufen, nicht auf einem Array, da Array.prototype.flatMap() nur Array-Rückgabewerte unterstützt.
const nonIterable = {
next() {
return { done: true };
},
};
const it = [nonIterable].values().flatMap((x) => x); // No error
Wenn Sie Ihre eigenen Iteratoren implementieren, sollten Sie in Betracht ziehen, sie iterierbar zu machen, indem Sie entweder die Iterator-Klasse subclassen oder eine [Symbol.iterator]()-Methode hinzufügen, die this zurückgibt.
Spezifikationen
| Spezifikation |
|---|
| ECMAScript® 2027 Language Specification> # sec-iterator.concat> |