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}

返回值:状态对象

说明:处理异常抛出

相关推荐
薛定谔的算法3 小时前
JavaScript数组操作完全指南:从基础到高级
前端·javascript·算法
拜无忧3 小时前
前端,用SVG 模仿毛笔写字绘画,defs,filter
前端·css·svg
FlowGram3 小时前
Flowgram 物料库建设思考与实践
前端
用户22152044278003 小时前
Promise实例方法和async、await语法糖
前端·javascript
普通码农3 小时前
uniapp开发微信小程序使用takeSnapshot截图保存分享
前端
snows_l4 小时前
MacOS 通过Homebrew 安装nvm
前端·macos
前端开发爱好者4 小时前
下一代全栈框架:Deno + Vite 的结合体!
前端·javascript·后端
CUGGZ4 小时前
前端部署,又有新花样?
前端·javascript
Zz_waiting.4 小时前
Javaweb 14.4 Vue3 视图渲染技术
前端·javascript·vue.js