Iterator() 构造函数
Limited availability
This feature is not Baseline because it does not work in some of the most widely-used browsers.
语法
参数
无。
返回值
一个新的 Iterator
对象。
异常
TypeError
-
当
new.target
是Iterator
函数本身时,例如当Iterator
构造函数本身被构造时。
描述
Iterator
代表一个抽象类——一个为其子类提供通用工具方法的类,但其本身并不用于实例化。它是所有其他迭代器类的超类,用于创建实现特定迭代算法的子类——即,Iterator
的所有子类必须按照迭代器协议的要求实现 next()
方法。由于 Iterator
本身并不提供 next()
方法,因此直接构造 Iterator
并不合理。
你也可以使用 Iterator.from()
来从一个现有的可迭代对象或迭代器对象创建一个 Iterator
实例。
示例
继承 Iterator
以下示例定义了一个允许迭代的自定义数据结构——Range
。使一个对象可迭代最简单的方法是提供一个生成器函数的形式的 [Symbol.iterator]()
方法:
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]
,同时使得迭代器辅助方法对返回的迭代器可用。
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,
});
// 避免 #RangeIterator 被外部访问
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
实例。
规范
Specification |
---|
Iterator Helpers # sec-iterator-constructor |
浏览器兼容性
BCD tables only load in the browser