Iterator() 构造函数
语法
参数
无。
返回值
一个新的 Iterator
对象。
异常
TypeError
-
当
new.target
本身是Iterator
函数时,即当Iterator
构造函数本身被构造时。
描述
Iterator
代表一个抽象类——一个为其子类提供通用实用程序的类,但它本身并不打算被实例化。它是所有其他迭代器类的超类,用于创建实现特定迭代算法的子类——即,Iterator
的所有子类都必须实现 next()
方法,如 迭代器协议 所要求的那样。由于 Iterator
实际上没有提供 next()
方法,因此直接构造一个 Iterator
没有任何意义。
您还可以使用 Iterator.from()
从现有的可迭代或迭代器对象创建一个 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
实例。
规范
规范 |
---|
迭代器帮助器 # sec-iterator-constructor |
浏览器兼容性
BCD 表格仅在浏览器中加载