ts的迭代器和生成器

在 TypeScript(以及 JavaScript)中,迭代器和生成器是用于处理集合数据(如数组、对象等)的强大工具。它们允许你按顺序访问集合中的元素,并提供了一种控制数据访问的方式。

迭代器(Iterator) 迭代器是一个对象,它定义了一个序列,并且提供了一种方法来访问这个序列的元素。迭代器对象实现了 Iterator 接口,该接口要求它有一个 next() 方法。

Iterable 接口 一个对象如果实现了Iterable接口,那么它就是可迭代的。这个接口要求对象必须有一个Symbol.iterator方法,这个方法返回一个迭代器对象。

Iterator 接口 迭代器对象必须实现Iterator接口。这个接口定义了next()方法,该方法返回一个对象,这个对象有两个属性:value和done。value表示当前的元素值,done是一个布尔值,表示是否还有更多的元素可以迭代。

1.可迭代对象(Iterable)

一个对象如果实现了[Symbol.iterator]方法,它就是可迭代的。这个方法必须返回一个迭代器对象。常见的内置可迭代对象包括:Array,String,Map,Set,arguments对象(可通过Array.from()或扩展运算符使用),DOM的NodeList(部分浏览器)。

ts 复制代码
const arr = [1, 2, 3];
console.log(arr[Symbol.iterator]); 

这些对象之所以能被for...of循环遍历,正是因为它们实现了Symbol.iterator方法。

2.迭代器(Iterator)

迭代器是一个带有next()方法的对象,调用next()返回{value,done}. value:当前值(当done:true时,value可省略或为undefined) done:布尔值,表示是否遍历完成。

ts 复制代码
const arr = [10, 20];
const iterator = arr[Symbol.iterator]();

console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());

注意:迭代器本身通常也是可迭代的(即它自己也有[Symbol.iterator()]),这样它就可以用于for...of。

3.for...of与展开运算符的工作原理
ts 复制代码
for (const item of [1, 2, 3]) {
  console.log(item);
}

背后的逻辑:

  • 获取[1,2,3] [Symbol.iterator]()
  • 不断调用.next()直到done:true

同理:

ts 复制代码
const str = "hi";
const chars = [...str];
console.log(chars)
手动实现一个可迭代对象
ts 复制代码
class Countdown {
  constructor(private start: number) {}

  [Symbol.iterator](): Iterator<number> {
    let current = this.start;
    return {
      next(): { value: number; done: boolean } {
        if (current < 0) {
          return { value: undefined, done: true };
        }
        return { value: current--, done: false };
      },
      // 可选:支持 return() 方法用于提前终止(如 break)
      return() {
        console.log("迭代被中断");
        return { value: undefined, done: true };
      }
    };
  }
}

// 使用
const countdown = new Countdown(3);
for (const n of countdown) {
  console.log(n); 
}
生成器(Generator):简化迭代器创建

生成器函数是创建迭代器的便捷方式。使用function* 定义,内部用yield暂停执行。

ts 复制代码
function* idGenerator() {
  let id = 1;
  while (true) {
    yield id++;
  }
}

const gen = idGenerator();
console.log(gen.next().value);
console.log(gen.next().value);

生成器函数返回一个生成器对象,它即是迭代器,也是可迭代对象。

你甚至可以让一个对象使用生成器作为[Symbol.iterator]

ts 复制代码
const myRange = {
  from: 1,
  to: 5,
  *[Symbol.iterator]() {
    for (let i = this.from; i <= this.to; i++) {
      yield i;
    }
  }
};

console.log([...myRange]);

迭代器协议总结:

协议:Iterable

方法:[Symbol.iterator]():Iterator

返回值:迭代器对象

说明:表示可被遍历
协议:Iterator

方法:next():{value,done}

返回值:状态对象

说明:提供下一个值
协议:可选

方法:return?():{value,done}

返回值:状态对象

说明:处理提前退出
协议:可选

方法:throw?():{value,done}

返回值:状态对象

说明:处理异常抛出

相关推荐
真的想不出名儿2 小时前
vue项目引入字体
前端·javascript·vue.js
胡楚昊2 小时前
Polar WEB(1-20)
前端
吃饺子不吃馅3 小时前
AntV X6图编辑器如何实现切换主题
前端·svg·图形学
余防3 小时前
XXE - 实体注入(xml外部实体注入)
xml·前端·安全·web安全·html
jump_jump3 小时前
前端部署工具 PinMe
运维·前端·开源
Baklib梅梅4 小时前
优秀文档案例解析:打造高效用户体验的最佳实践
前端·ruby on rails·前端框架·ruby
慧一居士4 小时前
VUE、jquery、React、Ant Design、element ui、bootstrap 前端框架的 功能总结,示例演示、使用场景介绍、完整对比总结
前端
GISer_Jing4 小时前
0926第一个口头OC——快手主站前端
开发语言·前端·javascript
MediaTea5 小时前
Jupyter Notebook:基于 Web 的交互式编程环境
前端·ide·人工智能·python·jupyter
少年阿闯~~5 小时前
CSS——重排和重绘
前端