docs(iterator): add Iterator object

This commit is contained in:
ruanyf
2026-09-24 17:06:42 +08:00
parent b5621acff1
commit 114c8afd03
+192 -22
View File
@@ -819,9 +819,194 @@ for (var n of fibonacci) {
上面的例子,会输出斐波纳契数列小于等于 1000 的项。如果当前项大于 1000,就会使用`break`语句跳出`for...of`循环。
## 遍历器对象的工具方法
## Iterator 对象
ES2025 为遍历器接口返回的遍历器对象,添加了一些工具方法,便于处理数据。
ES2025 正式提供了 Iterator 对象,作为遍历器的原型对象。这个对象可以作为抽象类,供其他类继承。
```javascript
class MyIterator extends Iterator {
next() {
// …
}
}
```
上面就是继承 Iterator 的例子,需要自己部署`next()`方法。
除了继承使用,这个对象还有一些静态方法,作为工具使用。另外,它还提供很多遍历器的实例方法。
### Iterator 对象的静态方法
Iterator 对象主要有下面两个静态方法。
- Iterator.from()
- Iterator.concat()
**(1)Iterator.from()**
这个方法接受一个部署了遍历器接口的对象作为参数,返回该对象的遍历器。
```javascript
const it = (function* () {
yield 1;
yield 2;
yield 3;
})();
const obj = {
[Symbol.iterator]() {
return it;
},
};
const it2 = Iterator.from(obj);
it2 === it // true
```
上面示例中,对象`obj`的遍历器是函数`it`,调用`Iterator.from(obj)`就会返回遍历器`it`,即上面例子的`it2`和`it`是同一个对象。
但是现实中,很多对象的遍历器接口是自定义的,只定义了`next()`方法,并不是真实的 Iterator 实例对象(即并未继承`Iterator.prototype`)。这种情况下,`Iterator.from()`会将自定义的遍历器对象,转成 Iterator 实例对象。
```javascript
const it = {
current: 0,
next() {
return { value: this.current++, done: false };
},
};
const obj = {
[Symbol.iterator]() {
return it;
},
};
const it2 = Iterator.from(obj);
it2 === it // false
it2.next() // {value: 0, done: false}
it.next() // {value: 1, done: false}
```
上面示例中,对象`obj`的遍历器是自定义对象`it`,它带有一个手工构造的`next()`方法,并不是 Iterator 的实例对象。这时,`Iterator.from(obj)`就会返回`it`的一个包装对象。`it2`和`it`并不是同一个对象,`it2`只是让`it`继承了 Iterator 对象的实例方法,`it`自身定义的`next()`方法还是不变的,因此`it2.next()`和`it.next()`移动的是同一个指针。
总之,`Iterator.from()`的目的就是获取对象的遍历器对象(`[System.iterator]()`方法的值),并确保该对象是 Iterator 的实例对象。
如果一个对象本身就是遍历器对象,那么`Iterator.from()`也可以用来直接转化该对象。
```javascript
// 示例一
const obj1 = (function* () {
yield 1;
yield 2;
yield 3;
})();
const obj2 = Iterator.from(obj1);
obj2 === obj1 // true
// 示例二
const obj3 = {
current: 0,
next() {
return { value: this.current++, done: false };
},
};
const obj4 = Iterator.from(obj4);
obj3 === obj4 // false
```
上面示例中,`Obj1`和`obj3`本身就是遍历器对象,`Iterator.from()`可以直接转换它们。`Obj1`是 Iterator 的实例对象,所以转换后不变,而`Obj3`不是 Iterator 实例对象,所以转换后变成了原对象的包装对象。
**(2)Iterator.concat()**
`Iterator.concat()`可以把多个遍历器对象合成一个对象(即按顺序遍历)。
```javascript
const a1 = [1,2];
const a2 = [3,4];
const a3 = [5,6];
const it = Iterator.concat(a1, a2, a3)
it.next() // {value: 1, done: false}
it.next() // {value: 2, done: false}
it.next() // {value: 3, done: false}
```
上面示例中,`Iterator.concat()`将`a1`、`a2`、`a3`三个数组的遍历器连接起来,可以顺序遍历。
它可以将不同类型对象的遍历器连接起来。
```javascript
const array = [1, 2, 3];
const set = new Set([4, 5, 6]);
function* gen() {
yield 7;
yield 8;
yield 9;
}
const it = Iterator.concat(array, set, gen());
[...it] // [1, 2, 3, 4, 5, 6, 7, 8, 9]
```
上面示例中,`Iterator.concat()`将三种不同类型的遍历器连接了起来。
如果参数是不可遍历对象,它会报错。
```javascript
const obj = {
next() {
return { done: true };
},
};
const it = Iterator.concat(obj); // 报错
```
上面示例中,`obj`不是符合要求的遍历器对象,所以`Iterator.concat()`就报错了。如果用`Iterator.from()`转换成合格对象,就不报错了。
```javascript
const obj = {
next() {
return { done: true };
},
};
const it = Iterator.concat(Iterator.from(Obj)); // 不报错
```
## Iterator 对象的实例方法
Iterator 对象的实例方法,基本上对应同名的数组方法,用法也类似,不同之处是,它只处理遍历器对象。下面是其中一些方法。
```javascript
- Iterator.prototype.every()
- Iterator.prototype.filter()
- Iterator.prototype.find()
- Iterator.prototype.flatMap()
- Iterator.prototype.forEach()
- Iterator.prototype.includes()
- Iterator.prototype.join()
- Iterator.prototype.map()
- Iterator.prototype.reduce()
- Iterator.prototype.some()
```
这些方法可以像数组方法一样链式使用。
```javascript
const result = Iterator.from(array)
.map(x => x * 2)
.filter(x => x > 10)
.take(3)
.toArray();
```
下面是一个实际的例子。
```javascript
const arr = ['a', '', 'b', '', 'c', '', 'd', '', 'e'];
@@ -835,26 +1020,11 @@ arr.values() // creates an iterator
// ['=b=', '=c=', '=d=']
```
上面示例中,arr 是一个数组,它的 values() 方法返回的是一个遍历器对象,以前要使用 for...of 循环来处理,现在有了工具方法,就可以直接链式处理了。
上面示例中,arr 是一个数组,它的 values() 方法返回的是一个遍历器对象,以前要使用 for...of 循环来处理,现在有了遍历器对象的实例方法,就可以直接链式处理了。
遍历器对象的工具方法,基本上与数组方法是对应的。
有三个实例方法是 Iterator 实例对象独有的。
- 返回遍历器对象的方法
- iterator.filter(filterFn)
- iterator.map(mapFn)
- iterator.flatMap(mapFn)
- 返回布尔值的方法
- iterator.some(fn)
- iterator.every(fn)
- 返回其他值的方法
- iterator.find(fn)
- iterator.reduce(reducer, initialValue?)
- 不返回值的方法
- iterator.forEach(fn)
以下是遍历器对象独有的方法。
- iterator.drop(limit):返回一个遍历器对象,丢弃前 limit 个成员。
- iterator.take(limit):返回一个遍历器对象,包含前 limit 个成员。
- iterator.toArray():返回一个数组,包含所有成员。
- Iterator.prototype.drop(limit):返回一个遍历器对象,丢弃前 limit 个成员。
- Iterator.prototype.take(limit):返回一个遍历器对象,包含前 limit 个成员。
- Iterator.prototype.toArray():返回一个数组,包含所有成员。