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}

返回值:状态对象

说明:处理异常抛出

相关推荐
IMPYLH几秒前
HTML 的 <tfoot> 元素
前端·javascript·html
像风一样自由20206 分钟前
42.VueReactNextjs如何为AI应用设计前端交互
前端·人工智能·大模型·交互·rag·智能体
鬼手点金6 分钟前
Claude Code示范案例-修复 Bug 工作流
java·服务器·前端·javascript·bug·openclaw
柳杉16 分钟前
用 GPT-6 Astra 和 Tripo3D 做智慧农业 3D 大屏:从调研到可巡检园区全流程实录
前端·ai编程·数据可视化
特创数字科技20 分钟前
【uni-app x】告别系统相机限制!三端通用自定义相机组件:任意布局、静默拍照、录像、水印叠加、连拍回图一次搞定
前端·数码相机·uni-app
IT_陈寒35 分钟前
用Vue时这个响应式陷阱坑了我一整天
前端·人工智能·后端
风骏时光牛马43 分钟前
企业客户信息管理数据库
前端
paopaokaka_luck1 小时前
个人综合管理小程序(echarts数据看板、健康数据记录与趋势查看、目标拆解和进度管理、日程待办与番茄钟、习惯打卡、收支统计、个人生活记录、跨模块智能提醒)
前端·javascript·spring·小程序·数据分析·echarts·生活
霸道流氓气质1 小时前
Graph Studio Web IDE 深度实战:可视化编排、断点调试与生产级运维全指南
运维·前端·ide