语法
js
new Iterator()
参数
无。
返回值
一个新的 Iterator
对象。
异常
TypeError
-
当
new.target
是Iterator
函数本身时,即当Iterator
构造函数本身被构造时。
描述
Iterator
代表一个抽象类——一个为子类提供通用实用程序的类,但本身不打算被实例化。它是所有其他迭代器类的超类,用于创建实现特定迭代算法的子类——即,所有 Iterator
的子类都必须根据 迭代器协议 实现 next()
方法。由于 Iterator
实际上不提供 next()
方法,因此直接构造 Iterator
没有意义。
您还可以使用 Iterator.from()
从现有的可迭代对象或迭代器对象创建 Iterator
实例。
示例
继承 Iterator
以下示例定义了一个自定义数据结构 Range
,它允许迭代。为了使对象可迭代,我们可以提供一个生成器函数形式的 [Symbol.iterator]()
方法。
js
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);
}
这可行,但不如内置迭代器那样好。有两个问题:
- 返回的迭代器继承自
Generator
,这意味着对Generator.prototype
的修改将影响返回的迭代器,这是一个抽象泄露。 - 返回的迭代器不继承自定义原型,这使得如果我们想向迭代器添加额外方法会更加困难。
我们可以通过继承 Iterator
来模仿内置迭代器(例如 map 迭代器)的实现。这使我们能够定义额外的属性,例如 [Symbol.toStringTag]
,同时使迭代器辅助方法在返回的迭代器上可用。
js
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);
}
如果您想创建许多自定义迭代器,继承模式很有用。如果您有一个现有的可迭代对象或迭代器对象,它不继承自 Iterator
,而您只想在其上调用迭代器辅助方法,您可以使用 Iterator.from()
来创建一个一次性的 Iterator
实例。
规范
规范 |
---|
ECMAScript® 2026 语言规范 # sec-iterator-constructor |
浏览器兼容性
加载中…