前端必刷系列之红宝书——第 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 版)

相关推荐
粥里有勺糖2 分钟前
用Trae做了个公众号小工具
前端·ai编程·trae
京东零售技术1 小时前
在京东 探索技术的无限可能
面试
棉花糖超人1 小时前
【从0-1的HTML】第2篇:HTML标签
前端·html
exploration-earth1 小时前
本地优先的状态管理与工具选型策略
开发语言·前端·javascript
OpenTiny社区1 小时前
开源之夏报名倒计时3天!还有9个前端任务有余位,快来申请吧~
前端·github
ak啊1 小时前
WebGL魔法:从立方体到逼真阴影的奇妙之旅
前端·webgl
hang_bro2 小时前
使用js方法实现阻止按钮的默认点击事件&触发默认事件
前端·react.js·html
哈贝#2 小时前
vue和uniapp聊天页面右侧滚动条自动到底部
javascript·vue.js·uni-app
用户90738703648642 小时前
pnpm是如何解决幻影依赖的?
前端
寒山李白2 小时前
Java 依赖注入、控制反转与面向切面:面试深度解析
java·开发语言·面试·依赖注入·控制反转·面向切面