Iterator() constructor
Baseline 2025Newly available
Since March 2025, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.
TheIterator() constructor is intended to be used as thesuperclass of other classes that create iterators. It throws an error when constructed by itself.
In this article
Syntax
new Iterator()Parameters
None.
Return value
A newIterator object.
Exceptions
TypeErrorWhen
new.targetis theIteratorfunction itself, i.e., when theIteratorconstructor itself is constructed.
Description
Iterator represents anabstract class — a class that provides common utilities for its subclasses, but is not intended to be instantiated itself. It is the superclass of all other iterator classes, and is used to create subclasses that implement specific iteration algorithms — namely, all subclasses ofIterator must implement anext() method as required by theiterator protocol. BecauseIterator doesn't actually provide thenext() method, it doesn't make sense to construct anIterator directly.
You can also useIterator.from() to create anIterator instance from an existing iterable or iterator object.
Examples
>Subclassing Iterator
The following example defines a custom data structure,Range, which allows iteration. To make an object iterable, we can provide a[Symbol.iterator]() method in the form of a generator function:
class Range { #start; #end; #step; constructor(start, end, step = 1) { this.#start = start; this.#end = end; this.#step = step; } *[Symbol.iterator]() { for (let value = this.#start; value <= this.#end; value += this.#step) { yield value; } }}const range = new Range(1, 5);for (const num of range) { console.log(num);}This works, but it isn't as nice as how built-in iterators work. There are two problems:
- The returned iterator inherits from
Generator, which means modifications toGenerator.prototypeare going to affect the returned iterator, which is a leak of abstraction. - The returned iterator does not inherit from a custom prototype, which makes it harder if we intend to add extra methods to the iterator.
We can mimic the implementation of built-in iterators, such asmap iterators, by subclassingIterator. This enables us to define extra properties, such as[Symbol.toStringTag], while making the iterator helper methods available on the returned iterator.
class Range { #start; #end; #step; constructor(start, end, step = 1) { this.#start = start; this.#end = end; this.#step = step; } static #RangeIterator = class extends Iterator { #cur; #s; #e; constructor(range) { super(); this.#cur = range.#start; this.#s = range.#step; this.#e = range.#end; } static { Object.defineProperty(this.prototype, Symbol.toStringTag, { value: "Range Iterator", configurable: true, enumerable: false, writable: false, }); // Avoid #RangeIterator from being accessible outside delete this.prototype.constructor; } next() { if (this.#cur > this.#e) { return { value: undefined, done: true }; } const res = { value: this.#cur, done: false }; this.#cur += this.#s; return res; } }; [Symbol.iterator]() { return new Range.#RangeIterator(this); }}const range = new Range(1, 5);for (const num of range) { console.log(num);}The subclassing pattern is useful if you want to create many custom iterators. If you have an existing iterable or iterator object which doesn't inherit fromIterator, and you just want to call iterator helper methods on it, you can useIterator.from() to create a one-timeIterator instance.
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-iterator-constructor> |