ECMAScript 2026
⚠️ Baseline Newly Available (March 2026)Iterator.concat()
Combine multiple iterables into a single lazy iterator.
Last updated: October 2026
Definition: Iterator.concat(it1, it2, ..., itN) creates a new Iterator object from a list of iterable objects. The new iterator yields values from each input iterable in sequence, lazily — values are pulled only as the consumer advances the iterator [citation:10].
🎬 Live Example
Five common Iterator.concat patterns. Click any button to see the output.
💡 Iterator.concat is lazy — it doesn't build an array.
Basic Syntax
Iterator.concat(it1)
Iterator.concat(it1, it2)
Iterator.concat(it1, it2, ..., itN)
// Returns: new Iterator object
// Lazy — yields values on demand
// Accepts synchronous iterables only
🎯 Syntax & Parameters
| Parameter | Type | Description |
|---|---|---|
it1..itN | iterable | Objects implementing the iterable protocol. Non-iterables throw TypeError. |
Basic Concatenation
const it = Iterator.concat([1, 2], [3, 4]);
[...it];
// [1, 2, 3, 4]
// Like Array.concat, but lazy
Any Iterable Works
Iterator.concat([1, 2], new Set([3, 4]), "ab");
// Yields: 1, 2, 3, 4, 'a', 'b'
// Strings, Sets, Maps, custom iterables — all valid
Pro tip: Built-in iterators (Map, Set, Array, String) all work directly.
Lazy Evaluation
function* infinite() {
let i = 0;
while (true) yield i++;
}
const it = Iterator.concat(infinite(), [999]);
it.next().value; // 0
it.next().value; // 1
it.next().value; // 2
// Never reaches [999] until infinite ends
Note: Iterables after the first infinite iterable will never be reached.
Passing Non-Iterable Iterators
const it = [1, 2].values(); // Iterator, not iterable
// Iterator.concat(it); // TypeError!
// Wrap with Iterator.from()
Iterator.concat(Iterator.from(it));
// Works
Important: Iterator.concat() takes ownership of iterators and closes them. Non-iterable iterators must be wrapped with Iterator.from().
Real-World: Map Union
const defaults = new Map([["theme", "dark"]]);
const userPrefs = new Map([["theme", "light"], ["lang", "en"]]);
const merged = new Map(
Iterator.concat(defaults, userPrefs)
);
// Map { 'theme' => 'light', 'lang' => 'en' }
// Map constructor uses the last value for duplicate keys
🎯 Iterator.concat vs Array.concat vs flatMap
| Method | Returns | Use when |
|---|---|---|
Iterator.concat | Lazy iterator | You don't need all values at once |
Array.concat | Eager array | You need a concrete array |
Iterator.flatMap | Lazy iterator | Mapping + flattening lazily |
⚠️ Common Mistakes
- Passing async iterables. Iterator.concat() is sync-only. Use
for await...oforArray.fromAsync()for async. - Passing non-iterable iterators directly. Wrap with
Iterator.from(). - Expecting an array. It returns an iterator. Convert with spread
[...it]orArray.from(it). - Combining infinite iterables. Iterables after the first infinite one will never be reached.
- Assuming browser support everywhere. Baseline March 2026 — check compatibility.
❓ Frequently Asked Questions
What does Iterator.concat() do in JavaScript?
Iterator.concat() creates a new iterator that yields values from multiple iterable objects in sequence. It is lazy — values are pulled only as the consumer advances the iterator, avoiding intermediate arrays.
What is the difference between Array.concat() and Iterator.concat()?
Array.concat() returns a new array and eagerly evaluates all elements. Iterator.concat() returns an iterator, is lazy, and can combine infinite iterables (though iterables after the first infinite one will never be reached).
When was Iterator.concat() added to JavaScript?
Iterator.concat() was approved as part of ECMAScript 2026 (June 2026). It reached Baseline Newly Available in March 2026 and is available in Chrome 146+, Firefox 147+, Safari 26.4+.
Can Iterator.concat() combine async iterables?
No. Iterator.concat() works with synchronous iterables only. For async iteration, use for await...of or Array.fromAsync().
Does Iterator.concat() consume the source iterables?
Yes. Iterator.concat() takes ownership of the iterators it creates from its arguments. When the combined iterator is closed, it closes the current underlying iterator. The source iterables themselves are not consumed unless they are also their own iterators.