快速理解JS迭代器、生成器

迭代器和生成器

JS的迭代器(Iterator)和生成器(Generator)是ECMAScript 2015(通常称为ES6)引入的两个重要特性,它们的引入主要是为了解决JavaScript中异步编程的一些问题,以及提供一种更简洁明了地处理集合数据的方式。
为什么把他们呢两个放在一起来看,因为生成器在用的时候可以依赖迭代器🦍🦧

迭代器(Iterator)

背景历史和作用:
在ES6之前,JavaScript中的异步编程主要依赖于回调函数,这会导致所谓的“回调地狱”问题,代码嵌套层次过多,难以阅读和维护。同时,处理像数组或对象这类集合数据时也不够方便。

迭代器模式是一种设计模式,它提供了一种方法顺序访问一个集合对象中各个元素, 而又不需要暴露该对象的内部表示。ES6中,引入了迭代器协议,并且内置了对迭代器的支持。迭代器协议定义了产生一系列值(无论是有限个还是无限个)的标准方式。

一个对象若要成为迭代器,需要实现next()方法,这个方法需要返回一个对象,该对象包含两个属性:value表示当前的数据成员的值,done是一个布尔值,表示遍历是否结束。

详细理解:
迭代器使得数据集合的遍历变得更加抽象和通用,无需关心数据的内部结构。比如说,数组是JavaScript中最常用的数据结构之一,for…of循环可以通过数组对象的迭代器来遍历数组元素,这是因为数组是可迭代的(iterable),即实现了[Symbol.iterator]方法。

let arr = [1, 2, 3, 4, 5];
let it = arr[Symbol.iterator](); // 获取迭代器对象
console.log(it.next()); // { value: 1, done: false }
console.log(it.next()); // { value: 2, done: false }
// ...

生成器(Generator)

背景历史和作用:
生成器是ES6中新增的另一个重要特性,可以理解为一种能够暂停执行和恢复执行的函数。生成器的引入,同样是为了解决异步编程的问题,并且进一步地简化迭代器的创建过程。

生成器函数在定义时用function*声明,函数内部可以使用yield关键字暂停函数执行并返回一个值,下一次调用生成器的next()方法时,会从暂停的位置继续执行。

详细理解:
生成器在处理异步操作时有极大的优势,它可以在某个操作未完成时暂停代码执行,等到异步操作完成再继续。这种能力让生成器看起来像是能够异步返回值的函数。

function* generatorExample() {
  yield '🥶';
  yield 2;
  return 'jack';
}

let gen = generatorExample();

console.log(gen.next()); // { value: '🥶', done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 'jack', done: true }

这里调用生成器函数产生了一个生成器对象这个对象是一个迭代器,当然,数组、Map等也是迭代器 所以生成器可以配合for...of循环使用,使得其实现的迭代逻辑更自然:

for (let value of generatorExample()) {
  console.log(value);
}
// 输出: 🥶 2

注意,生成器的return语句返回的值在for...of循环中是不会被遍历的,因为当done为true时循环就会结束。

生成器和迭代器最大的不同在于:迭代器通常是用来遍历数据集合的工具,而生成器提供了更强大的控制流程的能力,它不仅可以用于遍历数据,还能用于异步编程的场景。

随后,在ES7/ES2016引入了async/await,进一步改进了异步编程体验,async/await可以看做是基于Promise和生成器的一个更高层次的抽象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值