前端必刷系列之红宝书——第 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 循环来自动消费。
js 复制代码
// 迭代器对象
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 关键字可以将跟它后边的可迭代对象序列化为一连串值。
js 复制代码
// 定义生成器函数
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 版)

相关推荐
李白的天不白9 小时前
请求不到百度网址的原因
前端
多秋浮沉度华年9 小时前
electron 初始使用记录
javascript·arcgis·electron
Gary Studio9 小时前
Selinux编写
linux·服务器·前端
网络点点滴10 小时前
NPM的包版本管理
前端·npm·node.js
IT 青年10 小时前
网安面试经(13)
面试·网安
光影少年10 小时前
react性能优化比较好的办法有哪些?
前端·react.js·性能优化
fix一个write十个10 小时前
从零搭建音视频通话太痛苦?这个 Vue3 CallKit 让你 5 分钟搞定 1v1 + 群聊通话
前端·vue.js·github
竹林81810 小时前
用 wagmi v2 + WebSocket 硬磕 NFT 上架失败:一个前端开发者踩过的实时状态同步坑
javascript·next.js
豹哥学前端10 小时前
告别割裂式学习:待办清单项目,一次性掌握数组、本地存储与事件委托
前端·javascript