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

相关推荐
一只叫煤球的猫18 分钟前
手撕@Transactional!别再问事务为什么失效了!Spring-tx源码全面解析!
后端·spring·面试
foxhuli22936 分钟前
禁止ifrmare标签上的文件,实现自动下载功能,并且隐藏工具栏
前端
青皮桔1 小时前
CSS实现百分比水柱图
前端·css
失落的多巴胺1 小时前
使用deepseek制作“喝什么奶茶”随机抽签小网页
javascript·css·css3·html5
DataGear1 小时前
如何在DataGear 5.4.1 中快速制作SQL服务端分页的数据表格看板
javascript·数据库·sql·信息可视化·数据分析·echarts·数据可视化
影子信息1 小时前
vue 前端动态导入文件 import.meta.glob
前端·javascript·vue.js
青阳流月1 小时前
1.vue权衡的艺术
前端·vue.js·开源
样子20181 小时前
Vue3 之dialog弹框简单制作
前端·javascript·vue.js·前端框架·ecmascript
kevin_水滴石穿1 小时前
Vue 中报错 TypeError: crypto$2.getRandomValues is not a function
前端·javascript·vue.js
翻滚吧键盘1 小时前
vue文本插值
javascript·vue.js·ecmascript