前端必刷系列之红宝书——第 7 章

“红宝书” 通常指的是《JavaScript 高级程序设计》,这是一本由 Nicholas C. Zakas(尼古拉斯·扎卡斯)编写的 JavaScript 书籍,是一本广受欢迎的经典之作。这本书是一部翔实的工具书,满满的都是 JavaScript 知识和实用技术。

不管你有没有刷过红宝书,如果现在还没掌握好,那就一起来刷红宝书吧,go!go!go!

系列文章:

第一部分:基本知识(重点、反复阅读)

  1. 前端必刷系列之红宝书——第 1、2 章
  2. 前端必刷系列之红宝书——第 3 章
  3. 前端必刷系列之红宝书——第 4、5 章
  4. 前端必刷系列之红宝书——第 6 章

第二部分:进阶内容

  1. 前端必刷系列之红宝书——第 7 章

第 7 章 迭代器与生成器

ES6 规范新增了 2 个高级特性:迭代器和生成器

迭代器模式

JavaScript 中的迭代器是一种设计模式,它提供了一种遍历容器(如数组、字符串或其他可迭代对象)的方法。

  • 迭代器是一个可以由任意对象实现的接口,支持连续获取对象产出的每一个值。
  • 任何实现 Iterable 接口的对象都有一个 Symbol.iterator 属性,这个属性引用默认迭代器。
  • 默认迭代器就像一个迭代器工厂,也就是一个函数,调用之后会产生一个实现 Iterator 接口的对象。
  • 迭代器必须通过连续调用 next() 方法才能连续取的值,这个方法返回一个 IteratorObject。
  • 这个对象包含一个 done 属性和一个 value 属性
  • done 是一个布尔值,表示是否还有更多值可以访问。
  • value 包含迭代器返回的当前值。
  • 这个接口可以通过手动反复调用 next() 方法来消费,也可以通过原生消费者,比如 for-of 循环来自动消费。
// 迭代器对象
class Iterator {
  constructor(collection) {
    this.collection = collection;
    this.index = 0;
  }

  // 获取下一个元素
  next() {
    if (this.index < this.collection.length) {
      return { value: this.collection[this.index++], done: false };
    } else {
      return { done: true };
    }
  }
}

// 可迭代对象
class Iterable {
  constructor(collection) {
    this.collection = collection;
  }

  // 获取迭代器对象
  getIterator() {
    return new Iterator(this.collection);
  }
}

// 使用迭代器遍历集合
const array = [1, 2, 3, 4, 5];
const iterable = new Iterable(array);
const iterator = iterable.getIterator();

while (true) {
  const { value, done } = iterator.next();
  if (done) break;
  console.log(value);
}
  • 迭代器在处理大量数据时非常有用,可以按需生成数据,而不必一次性加载整个集合。
  • 可以通过迭代器实现自定义数据结构的遍历

生成器

在 JavaScript 中,生成器(Generator)是一种特殊类型的函数,它允许你在需要时暂停和恢复函数的执行。生成器函数使用 function* 关键字进行定义,并包含一个或多个使用 yield 语句产生值的区块。生成器提供了一种更灵活的控制流,特别适用于异步编程。

  • 生成器是一种特殊的函数,调用之后会返回一个生成器对象
  • 生成器对象实现了 Iterable 接口,因此可用在任何消费可迭代对象的地方。
  • 生成器的独特之处在于支持 yield 关键字,这个关键字能暂停执行生成器函数。
  • 使用 yield 关键字还可以通过 next() 方法接受输入和产生输出。
  • 在加上星号之后,yield 关键字可以将跟它后边的可迭代对象序列化为一连串值。
// 定义生成器函数
function* myGenerator() {
    yield 1;
    yield 2;
    yield 3;
}

// 调用生成器函数不会执行函数体,而是返回一个生成器对象。
// 可以通过调用生成器对象的 `next()` 方法来启动或恢复生成器的执行。
let gen = myGenerator();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }

// 生成器与 Promise 一起使用,可以实现更具可读性和易维护性的异步代码。
// async/await 就是生成器的语法糖
function* asyncGenerator() {
    try {
        const result = yield fetchData(); // fetchData 返回一个 Promise
        console.log(result);
    } catch (error) {
        console.error(error);
    }
}

async function runAsyncGenerator() {
    const gen = asyncGenerator();
    const { value, done } = await gen.next();
    if (!done) {
        // 处理异步结果
    }
}

未完待续…

参考资料

《JavaScript 高级程序设计》(第 4 版)

原文链接:https://juejin.cn/post/7325652953540575243 作者:Bigger

(0)
上一篇 2024年1月20日 下午4:00
下一篇 2024年1月20日 下午4:10

相关推荐

发表回复

登录后才能评论