ES6/ES11知识点 续五

news2025/5/10 18:38:21

迭代器【Iterator】

ES6 中的**迭代器(Iterator)**是 JavaScript 的一种协议,它定义了对象如何被逐个访问。迭代器与 for…of、扩展运算符、解构赋值等语法密切相关。

📘 迭代器工作原理

ES6 迭代器的工作原理基于两个核心机制:

🌟 可迭代协议(Iterable Protocol)

如果一个对象实现了 Symbol.iterator 方法,并返回一个迭代器对象,那么它就是可迭代的(Iterable),可以用于:

  • for…of
  • 解构赋值(如 [a, b] = iterable)
  • … 扩展运算符
  • Array.from()
const iterable = {
  [Symbol.iterator]() {
    let i = 0;
    return {
      next() {
        return i < 3 ? { value: i++, done: false } : { done: true };
      }
    };
  }
};

for (const val of iterable) {
  console.log(val); // 0 1 2
}

⚙️迭代器协议(Iterator Protocol)

迭代器对象必须具有 next() 方法,每次调用返回一个对象:

{ value: any, done: boolean }

含义:

  • value: 当前值
  • done: false: 迭代未结束
  • done: true: 迭代结束

当 done: true 时,value 可选,将被忽略

🔄 for…of 背后的流程

等价于下面这个展开流程:

const iterator = iterable[Symbol.iterator]();
let result = iterator.next();
while (!result.done) {
  const value = result.value;
  // 执行代码块
  result = iterator.next();
}

📦 内置可迭代对象如何实现?

例如数组:

const arr = [10, 20, 30];
const iter = arr[Symbol.iterator]();

iter.next(); // { value: 10, done: false }
iter.next(); // { value: 20, done: false }

浏览器底层实现了数组的 Symbol.iterator 方法,它会返回一个迭代器对象。

🧠 迭代器的本质理解

  • Symbol.iterator 是告诉 JavaScript:我可以被 for…of 遍历
  • 返回的迭代器对象 next() 方法控制了“值从哪里来”和“什么时候结束”
  • 你也可以用 yield(生成器)简化构建逻辑

🛠️ 手动创建一个迭代器

function createIterator(arr) {
  let index = 0;
  return {
    next() {
      if (index < arr.length) {
        return { value: arr[index++], done: false };
      } else {
        return { value: undefined, done: true };
      }
    }
  };
}

const it = createIterator(['a', 'b', 'c']);
console.log(it.next()); // { value: 'a', done: false }
console.log(it.next()); // { value: 'b', done: false }
console.log(it.next()); // { value: 'c', done: false }
console.log(it.next()); // { value: undefined, done: true }

🚀 使对象可被 for…of 遍历

const iterableObj = {
  data: [10, 20, 30],
  
  [Symbol.iterator]() {
    let i = 0;
    const data = this.data;
    return {
      next() {
        return i < data.length
          ? { value: data[i++], done: false }
          : { done: true };
      }
    };
  }
};

for (const val of iterableObj) {
  console.log(val);
}
// 输出:10 20 30

📦 内置可迭代对象

类型 可迭代? 示例
数组 ✅ for (let x of [1,2,3])
字符串 ✅ for (let c of ‘abc’)
Set / Map ✅ for (let e of new Set())
arguments ✅ for (let a of arguments)
DOM NodeList ✅ for (let el of nodelist)
普通对象 ❌ { a: 1 } ❌不能直接 for…of

🧙‍♂️ 配合生成器使用(语法糖)

function* gen() {
  yield 1;
  yield 2;
  yield 3;
}
const g = gen();
console.log(g.next()); // { value: 1, done: false }

for (const x of gen()) {
  console.log(x); // 1, 2, 3
}

✅ 判断是否可迭代

function isIterable(obj) {
  return typeof obj[Symbol.iterator] === 'function';
}

类数组对象添加自定义迭代器

方式一

const arrayLike = {
  0: 'a',
  1: 'b',
  2: 'c',
  length: 3,

  [Symbol.iterator]() {
    let index = 0;
    return {
      next: () => {
        return index < this.length
          ? { value: this[index++], done: false }
          : { done: true };
      }
    };
  }
};

for (const val of arrayLike) {
  console.log(val); // 输出:a, b, c
}

方式二

使用生成器方式更优雅

const arrayLike = {
  0: 'x',
  1: 'y',
  2: 'z',
  length: 3,

  *[Symbol.iterator]() {
    for (let i = 0; i < this.length; i++) {
      yield this[i];
    }
  }
};

for (const val of arrayLike) {
  console.log(val); // 输出:x, y, z
}

生成器

在 ES6 中,生成器(Generator)是一种特殊的函数,能控制函数的执行流程,支持按需产出(惰性求值),适合处理迭代、异步、状态机等场景。

🧱 基本语法

function* myGenerator() {
  yield 1;
  yield 2;
  yield 3;
}
  • 使用 function* 定义生成器函数(注意星号 *)。
  • 内部使用 yield 表达式产生值。
  • 调用生成器函数返回的是一个迭代器对象。

🚀 调用与执行流程

const 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 }
  • 每次调用 next(),函数执行到下一个 yield 停下来,返回一个 { value, done } 对象。
  • 最后 done: true 表示完成。

🔁 配合 for…of

for (const val of myGenerator()) {
  console.log(val); // 输出:1, 2, 3
}

🧠 生成器的高级用法

✅ 接收外部值

function* gen() {
  const a = yield 1;
  const b = yield a + 2;
  return b;
}

const it = gen();

console.log(it.next());       // { value: 1, done: false }
console.log(it.next(10));     // { value: 12, done: false }
console.log(it.next(100));    // { value: 100, done: true }
  • yield 表达式可以接收传入的值,作为上一个 yield 的返回值。

🛠 典型应用场景

生成无限序列

function* idGenerator() {
  let id = 0;
  while (true) yield id++;
}

const ids = idGenerator();
console.log(ids.next().value); // 0
console.log(ids.next().value); // 1

自定义迭代器

const obj = {
  *[Symbol.iterator]() {
    yield 1;
    yield 2;
    yield 3;
  }
};

for (const x of obj) {
  console.log(x); // 输出:1, 2, 3
}

与异步协程结合(配合 async/await 或库如 co)

生成器可用于构造异步流程控制逻辑,尽管现在大多数场景被 async/await 替代。

yield* 的作用(委托子生成器)或生成器和 async/await 的区别

🔄 yield*:委托另一个生成器或可迭代对象

yield* 表达式可以将执行控制权交给另一个生成器或可迭代对象,就像“嵌套展开”。

✅ 示例 1:委托另一个生成器

function* inner() {
  yield 'a';
  yield 'b';
}

function* outer() {
  yield 'start';
  yield* inner(); // 委托 inner 生成器
  yield 'end';
}

for (const val of outer()) {
  console.log(val); // 输出:start, a, b, end
}

✅ 示例 2:委托数组

function* gen() {
  yield* [1, 2, 3];
}

console.log([...gen()]); // [1, 2, 3]

⚙️ 生成器 vs async/await

特性生成器(Generator)async/await
关键字function*, yieldasync function, await
控制流程方式手动通过 .next() 推进自动推进
异步支持不直接支持(需配合库)原生支持 Promise
返回值迭代器对象Promise
适合场景同步流程控制、数据生成异步流程控制

🔧 示例对比

1️⃣ 生成器实现异步流程(配合库如 co)

function* asyncTask() {
  const data = yield fetch('...');
  console.log(data);
}
// 需要外部 runner 自动推进

2️⃣ async/await 简洁实现

async function asyncTask() {
  const data = await fetch('...');
  console.log(data);
}

异步生成器 async function* 的基本用法

async function* asyncGenerator() {
  let i = 0;
  while (i < 3) {
    await new Promise(resolve => setTimeout(resolve, 1000)); // 模拟异步操作
    yield i++;
  }
}

// 使用 for await...of 来消费异步生成器
(async () => {
  for await (const val of asyncGenerator()) {
    console.log(val); // 每秒输出一个数字:0, 1, 2
  }
})();

异步分页加载

async function* fetchPages(total) {
  for (let page = 1; page <= total; page++) {
    const data = await fetch(`https://api.example.com/data?page=${page}`);
    const json = await data.json();
    yield json.items;
  }
}

(async () => {
  for await (const items of fetchPages(3)) {
    console.log('Page items:', items);
  }
})();

总结

  • yield* 是 生成器中的“合并子迭代器”工具。
  • async/await 是语法更清晰的异步生成器替代方案,自动推进,适合处理 Promise。
  • 生成器仍适用于同步状态控制、迭代器构造、无限序列、DSL 构建等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2372530.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

sqli-labs靶场18-22关(http头)

目录 less18&#xff08;user-agent&#xff09; less19&#xff08;referer&#xff09; less20&#xff08;cookie&#xff09; less21&#xff08;cookie&#xff09; less22&#xff08;cookie&#xff09; less18&#xff08;user-agent&#xff09; 这里尝试了多次…

Android系统架构模式分析

本文系统梳理Android系统架构模式的演进路径与设计哲学&#xff0c;希望能够借此探索未来系统的发展方向。有想法的同学可以留言讨论。 1 Android层次化架构体系 1.1 整体分层架构 Android系统采用五层垂直架构&#xff0c;各层之间通过严格接口定义实现解耦&#xff1a; 应用…

Web前端VSCode如何解决打开html页面中文乱码的问题(方法2)

Web前端—VSCode如何解决打开html页面中文乱码的问题&#xff08;方法2&#xff09; 1.打开VScode后&#xff0c;依次点击 文件 >> 首选项 >> 设置 2.打开设置后&#xff0c;依次点击 文本编辑器 >> 文件&#xff08;或在搜索框直接搜索“files.autoGuessEnc…

单调栈模版型题目(3)

单调栈型题目贡献法 基本模版 这是数组a中的 首先我们要明白什么叫做贡献&#xff0c;在一个数组b{1,3,5}中&#xff0c;连续包含1的连续子数组为{1}&#xff0c;{1,3}&#xff0c;{1,3,5}&#xff0c;一共有三个&#xff0c;这三个数一共能组成6个连续子数组&#xff0c;而其…

ts axios中报 Property ‘code‘ does not exist on type ‘AxiosResponse<any, any>‘

ts语法有严格的格式&#xff0c;如果我们在处理响应数据时&#xff0c;出现了axios响应中非默认字段&#xff0c;就会出现标题那样的警告&#xff0c;我们可以通过创建axios.dt.ts解决这个问题 下面是我在开发中遇到的警告&#xff0c;code并不是axios默认返回的字段&#xff0…

[AI Tools] Dify 工具插件上传指南:如何将插件发布到官方市场

Dify 作为开源的 LLM 应用开发平台,不仅支持本地化插件开发,也提供了插件市场机制,让开发者能够将自己构建的插件发布并供他人使用。本文将详细介绍如何将你开发的 Dify Tools 插件上传至官方插件市场,包括 README 编写、插件打包、仓库 PR 等核心步骤。 一、准备 README 文…

用react实现一个简单的三页应用

下面是一个使用 React Router 的简单示例&#xff0c;演示了如何在 React 应用中实现页面之间的导航。 &#x1f6e0;️ 第一步&#xff1a;使用 Vite 创建项目 npm create vitelatest my-router-app -- --template react cd my-router-app npm install&#x1f680; 第二步&a…

Go使用Gin写一个对MySQL的增删改查服务

首先用SQL创建一个包含id、name属性的users表 create table users (id int auto_incrementprimary key,name varchar(255) null );查询所有用户信息&#xff1a; func queryData(db *sql.DB, w http.ResponseWriter) {rows, err : db.Query("SELECT * FROM users"…

Xcode16.3配置越狱开发环境

首先先在https://developer.apple.com/xcode/resources/ 这里面登陆Apple账号&#xff0c;然后访问url下载 https://download.developer.apple.com/Developer_Tools/Xcode_16.3/Xcode_16.3.xip 1、安装theos https://theos.dev/docs/installation-macos 会安装到默认位置~/th…

SCADA|KIO程序导出变量错误处理办法

哈喽,你好啊,我是雷工! 最近在用KingSCADA3.52版本的软件做程序时,在导出变量进行批量操作时遇到问题,现将解决办法记录如下。 以下为解决过程。 01 问题描述 在导出KIO变量时,选择*.xls格式和*.xlsx时均会报错: 报如下错误: Unknown error 0x800A0E7A ADODB Connectio…

【漫话机器学习系列】249.Word2Vec自然语言训练模型

【自然语言处理】用 Word2Vec 将词语映射到向量空间详解 一、背景介绍 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;我们常常需要将文本信息转化为机器能够理解和处理的形式。传统的方法&#xff0c;如 one-hot编码&#xff0c;虽然简单&#xff0c;但存在严重…

云轴科技ZStack入选赛迪顾问2025AI Infra平台市场发展报告代表厂商

DeepSeek凭借低成本、高性能、开源优势带来的蝴蝶效应依然在持续影响企业AI应用部署。尤其在数据安全备受关注的背景下&#xff0c;私有化部署已经成为企业应用AI大模型的优选方案。赛迪顾问在近期发布的《2025中国AI Infra平台市场发展研究报告》中认为&#xff0c;在推理算力…

安达发|人力、机器、物料——APS排程软件如何实现资源最优配置?

引言&#xff1a;制造业资源优化的核心挑战 在现代制造业中&#xff0c;人力、机器、物料是生产运营的三大核心资源。如何让这些资源高效协同&#xff0c;避免浪费&#xff0c;是企业降本增效的关键。然而&#xff0c;许多制造企业仍面临以下问题&#xff1a; 人力安排不合理…

【软件测试】软件缺陷(Bug)的详细描述

目录 一、软件缺陷(Bug) 1.1 缺陷的判定标准 1.2 缺陷的生命周期 1.3 软件缺陷的描述 1.3.1 提交缺陷的要素 1.3.2 Bug 的级别 1.4 如何发现更多的 Bug? 1.5 缺陷的有效管理 1.5.1 缺陷的编写 1.5.2 缺陷管理工具 1.5.2.1 缺陷管理 1.5.2.2 用例管理 一、软件缺陷…

HTTP传输大文件的方法、连接管理以及重定向

目录 1. HTTP传输大文件的方法 1.1. 数据压缩 1.2. 分块传输 1.3. 范围请求 1.4. 多段数据 2. HTTP的连接管理 2.1. 短连接 2.2. 长连接 2.3. 队头阻塞 3. HTTP的重定向和跳转 3.1. 重定向的过程 3.2. 重定向状态码 3.3. 重定向的应用场景 3.4. 重定向的相关问题…

图像来源:基于协同推理的双视角超声造影分类隐式数据增强方法|文献速递-深度学习医疗AI最新文献

Title 题目 Image by co-reasoning: A collaborative reasoning-based implicit data augmentation method for dual-view CEUS classification 图像来源&#xff1a;基于协同推理的双视角超声造影分类隐式数据增强方法 01 文献速递介绍 结合了B型超声&#xff08;BUS&…

dotnet core c#调用Linux c++导出函数

1.声明C++导出函数 platform_export.h // // Created by dev on 5/6/25. //#ifndef PLATFORM_EXPORT_H #define PLATFORM_EXPORT_H #if defined(_WIN32)#ifdef LIB_EXPORTS#define LIB_API __declspec(dllimport)#else#define LIB_API __declspec(dllimport)#endif #else#ifde…

宁德时代区块链+数字孪生专利解析:去中心化身份认证重构产业安全底座

引言&#xff1a;当动力电池巨头瞄准数字孪生安全 2025年5月6日&#xff0c;金融界披露宁德时代未来能源&#xff08;上海&#xff09;研究院与母公司宁德时代新能源科技股份有限公司联合申请的一项关键专利——“身份验证方法、系统、电子设备及存储介质”。这项技术将区块链…

1.微服务概念

1.单体、分布式、集群 先理解单体、集群、分布式这些概念 1.单体 一个系统业务量很小的时候,所有的代码都放在一个项目中&#xff0c;然后这个项目部署在一台服务器上就好了。整个项目所有的服务都由这台服务器提供。这就是单机结构. 1.1 优点 单体应用开发简单,部署测试简单 …

基于SSM实现的健身房系统功能实现八

一、前言介绍&#xff1a; 1.1 项目摘要 随着社会的快速发展和人们健康意识的不断提升&#xff0c;健身行业也在迅速扩展。越来越多的人加入到健身行列&#xff0c;健身房的数量也在不断增加。这种趋势使得健身房的管理变得越来越复杂&#xff0c;传统的手工或部分自动化的管…