当前位置: 首页 > news >正文

ES6 迭代器 (`Iterator`)使用总结

Iterator(迭代器)是 ES6 引入的一种 接口,用于 顺序访问 可迭代对象ArraySetMapStringarguments、自定义对象等)。
Iterator(迭代器)的作用有三个:

  1. 为各种数据结构提供一个统一的、简便的访问接口
  2. 使数据结构的成员能够按某种次序排列
  3. ES6 创造了一种新的遍历命令 for…of 循环,Iterator 接口主要供 for…of 消费

1. 迭代器的基本概念

(1) 迭代器是什么?

  • 迭代器是一种 特殊对象,提供 next() 方法,每次调用都会返回:
    { value: 当前值, done: 是否完成 }
    
  • done: true 时,表示迭代结束。

Iterator 的遍历过程

// Iterator 的遍历过程如下:
1. 创建一个指针对象,指向当前数据结构的起始位置
2. 第一次调用指针对象的 next 方法,可以将指针指向数据结构的第一个成员
3. 第二次调用指针对象的 next 方法,指针就指向数据结构的第二个成员
4. 不断调用指针对象的 next 方法,直到它指向数据结构的结束位置// 每一次调用 next 方法,都会返回一个包含 value 和 done 两个属性的对象
{value: 当前成员的值,done: 布尔值,表示遍历是否结束
}

2. 生成迭代器

(1) 手动创建迭代器

function createIterator(arr) {let index = 0;return {next: function () {return index < arr.length? { value: arr[index++], done: false }: { value: undefined, done: true };}};
}let iterator = createIterator(["a", "b", "c"]);
console.log(iterator.next()); // { value: 'a', done: false }
console.log(iterator.next()); // { value: 'b', done: false }
console.log(iterator.next()); // { value: 'c', done: false }
console.log(iterator.next()); // { value: undefined, done: true }

📌 每次 next() 调用,都会返回 value 并前进


(2) 使用 Symbol.iterator

所有 可迭代对象ArraySetMap 等)都有 默认的迭代器,可以用 Symbol.iterator 访问:

let arr = ["x", "y", "z"];
let iterator = arr[Symbol.iterator]();console.log(iterator.next()); // { value: 'x', done: false }
console.log(iterator.next()); // { value: 'y', done: false }
console.log(iterator.next()); // { value: 'z', done: false }
console.log(iterator.next()); // { value: undefined, done: true }

📌 数组、字符串、Set、Map 都有 Symbol.iterator,可直接迭代


(3) 自定义对象的迭代器

普通对象没有默认迭代器,需手动实现:

let myObj = {data: [10, 20, 30],[Symbol.iterator]: function () {let index = 0;return {next: () => {return index < this.data.length? { value: this.data[index++], done: false }: { value: undefined, done: true };}};}
};let iter = myObj[Symbol.iterator]();
console.log(iter.next()); // { value: 10, done: false }
console.log(iter.next()); // { value: 20, done: false }
console.log(iter.next()); // { value: 30, done: false }
console.log(iter.next()); // { value: undefined, done: true }

📌 对象没有默认迭代器,需实现 Symbol.iterator 才能用 for...of


3. for...of 遍历迭代器

所有 实现 Symbol.iterator 的对象,都可以用 for...of 遍历:

let arr = ["A", "B", "C"];for (let char of arr) {console.log(char);
}
// A
// B
// C

📌 相比 forEach()for...of 可与 breakcontinue 配合使用


4. 可迭代对象

可以使用 for...ofSymbol.iterator 的对象

  • Array
  • String
  • Set
  • Map
  • arguments
  • NodeList
  • 自定义对象(需实现 Symbol.iterator

5. SetMap 的迭代器

(1) Set 迭代

let mySet = new Set(["apple", "banana", "cherry"]);
let setIter = mySet[Symbol.iterator]();console.log(setIter.next()); // { value: 'apple', done: false }
console.log(setIter.next()); // { value: 'banana', done: false }
console.log(setIter.next()); // { value: 'cherry', done: false }
console.log(setIter.next()); // { value: undefined, done: true }

📌 Set 按插入顺序存储,迭代返回唯一值。


(2) Map 迭代

let myMap = new Map([["name", "Alice"],["age", 25]
]);for (let [key, value] of myMap) {console.log(key, value);
}
// name Alice
// age 25

📌 Map 迭代时返回 [key, value] 数组。


6. 迭代器 vs 生成器

特性迭代器 (Iterator)生成器 (Generator)
创建方式手动实现 next()function* 生成
使用 Symbol.iterator需要手动实现生成器自动实现
可暂停执行❌ 否✅ 是(可 yield

示例:生成器

function* generatorFunction() {yield "A";yield "B";yield "C";
}let gen = generatorFunction();
console.log(gen.next()); // { value: 'A', done: false }
console.log(gen.next()); // { value: 'B', done: false }
console.log(gen.next()); // { value: 'C', done: false }
console.log(gen.next()); // { value: undefined, done: true }

📌 生成器更简洁,支持 yield 暂停执行


7. Iterator 使用场景

7.1 解构赋值

// 对数组和 Set 结构进行解构赋值时,会默认调用 Iterator 接口
let set = new Set().add('a').add('b').add('c');
let [x, y] = set; // x='a'; y='b'

7.2 扩展运算符

// 扩展运算符(...)也会调用默认的 Iterator 接口
let str = 'hello';
[...str] // ['h', 'e', 'l', 'l', 'o']let arr = ['b', 'c'];
['a', ...arr, 'd']
// ['a', 'b', 'c', 'd']

7.3 yield*

// yield* 后面跟的是一个可遍历的结构,它会调用该结构的遍历器接口
let generator = function* () {yield 1;yield* [2, 3, 4];yield 5;
};for (let v of generator()) {console.log(v);
}
// 1, 2, 3, 4, 5

8. 注意事项

8.1 对象的 for…of 循环

// 对象默认不具备 Iterator 接口,不能直接使用 for...of
let obj = { a: 1, b: 2, c: 3 };
for (let value of obj) {console.log(value); // TypeError: obj is not iterable
}// 正确的遍历对象方式
// 1. 使用 Object.keys()
for (let key of Object.keys(obj)) {console.log(key + ': ' + obj[key]);
}// 2. 使用 Object.entries()
for (let [key, value] of Object.entries(obj)) {console.log(key + ': ' + value);
}

8.2 Iterator 接口与 Generator 函数

// 使用 Generator 函数实现 Iterator 接口
let obj = {*[Symbol.iterator]() {yield 'hello';yield 'world';}
};for (let x of obj) {console.log(x);
}
// hello
// world

9. 最佳实践

9.1 为类部署 Iterator 接口

class Collection {constructor() {this.items = [];}add(item) {this.items.push(item);}*[Symbol.iterator]() {for (let item of this.items) {yield item;}}
}let collection = new Collection();
collection.add('foo');
collection.add('bar');for (let value of collection) {console.log(value);
}
// foo
// bar

9.2 异步迭代器

// ES2018 引入了异步迭代器
const asyncIterable = {async *[Symbol.asyncIterator]() {yield 'hello';yield 'async';yield 'iteration';}
};(async () => {for await (const x of asyncIterable) {console.log(x);}
})();
// hello
// async
// iteration

10. 适用场景

适用于

  1. 遍历数组、字符串、Set、Map
  2. 自定义可迭代对象
  3. 流式处理数据(类似分页加载)
  4. 避免一次性加载大数据(生成器)

11. 总结

  • Iterator 是 ES6 提供的一种接口,用于顺序访问集合。
  • Symbol.iterator 让对象变成可迭代,可用于 for...ofspread
  • SetMapArrayString 默认实现 Symbol.iterator,可直接迭代。
  • 生成器 (Generator) 自动创建迭代器,可暂停执行 (yield),更强大。

相关文章:

ES6 迭代器 (`Iterator`)使用总结

Iterator&#xff08;迭代器&#xff09;是 ES6 引入的一种 接口&#xff0c;用于 顺序访问 可迭代对象&#xff08;Array、Set、Map、String、arguments、自定义对象等&#xff09;。 Iterator&#xff08;迭代器&#xff09;的作用有三个&#xff1a; 为各种数据结构提供一个…...

信用修复和失联修复的区别

失联修复和信用修复是两个不同的概念&#xff0c;在目的、操作方式和应用场景上都有所区别。 失联修复 失联修复主要是指在金融催收行业中&#xff0c;当债务人的联系方式&#xff08;通常是手机号码&#xff09;发生改变&#xff0c;导致无法联系到债务人时&#xff0c;催收公…...

2025蓝桥杯JAVA编程题练习Day3

1.黛玉泡茶【算法赛】 问题描述 话说林黛玉闲来无事&#xff0c;打算在潇湘馆摆个茶局&#xff0c;邀上宝钗、探春她们一起品茗赏花。黛玉素来讲究&#xff0c;用的茶杯也各有不同&#xff0c;大的小的&#xff0c;高的矮的&#xff0c;煞是好看。这不&#xff0c;她从柜子里…...

[论文阅读] Knowledge Fusion of Large Language Models

Knowledge Fusion of Large Language Models (FuseLLM) Methodology 整体Pipeline如下图所示 不同的动物代表不同的LLM。左边第一&#xff0c;第二分别是Ensemble以及Weight Merging方法。最右侧为本文提出的FuseLLM。 Ensemble: 融合多个models的预测结果&#xff0c;比如…...

deepseek来讲lua

Lua 是一种轻量级、高效、可嵌入的脚本语言&#xff0c;广泛应用于游戏开发、嵌入式系统、Web 服务器等领域。以下是 Lua 的主要特点和一些基本概念&#xff1a; 1. 特点 轻量级&#xff1a;Lua 的核心非常小&#xff0c;适合嵌入到其他应用程序中。高效&#xff1a;Lua 的执…...

探索 Spring Cloud Alibaba:开启微服务架构新时代

一、引言 在当今数字化浪潮中&#xff0c;软件系统的规模和复杂度不断攀升&#xff0c;传统的单体架构逐渐难以满足快速迭代、高并发处理以及灵活扩展的需求。微服务架构应运而生&#xff0c;它将一个大型的应用拆分成多个小型、自治的服务&#xff0c;每个服务专注于特定的业务…...

【数据结构】(6) LinkedList 链表

一、什么是链表 1、链表与顺序表对比 不同点LinkedListArrayList物理存储上不连续连续随机访问效率O(N)O(1&#xff09;插入、删除效率O(1)O(N) 3、链表的分类 链表根据结构分类&#xff0c;可分为单向/双向、无头结点/有头节点、非循环/循环链表&#xff0c;这三组每组各取…...

【工具变量】上市公司企业渐进式创新程度及渐进式创新锁定数据(1991-2023年)

测算方式&#xff1a; 参考顶刊《经济研究》孙雅慧&#xff08;2024&#xff09;老师的做法&#xff0c;用当期创新和往期创新的内容重叠度作为衡量渐进式创新程度的合理指标。通过搜集海量专利摘要&#xff0c;测算当前专利申请和既有专利的内容相似度&#xff0c;反映企业在…...

07_任务状态——改进播放控制

一、声明 在05和06的程序里面可以达到的一个效果就是很完美的播放音乐&#xff0c;并且不会影响到其它任务的运行&#xff0c;但是这个代码有一个弊端就是要么创建任务从头开始播放要么就直接删除任务。 我们现在的程序就增加了音乐的暂停和恢复的功能&#xff0c;那么能够达到…...

【R语言】apply函数族

在R语言中使用循环操作时是使用自身来实现的&#xff0c;效率较低。所以R语言有一个符合其统计语言出身的特点&#xff1a;向量化。R语言中的向量化运用了底层的C语言&#xff0c;而C语言的效率比高层的R语言的效率高。 apply函数族主要是为了解决数据向量化运算的问题&#x…...

Retrieval-Augmented Generation,检索增强生成流程

RAG流程 用户输入接收 系统接收用户输入的查询问题或文本内容&#xff0c;例如“李白有哪些著名的作品&#xff1f;”用户输入可以通过自然语言处理&#xff08;NLP&#xff09;模型的输入端口或用户交互界面&#xff08;如聊天应用、搜索引擎输入框等&#xff09;接收。 查询…...

[AI][本地部署]离线升级后报ChromeDb错误

【背景】 升级了OpenWebUI&#xff0c;在离线环境下补足了很多需要的Package后终于成功启动了Backend的服务&#xff0c;但是一旦上传文件&#xff0c;就会报ChromaDb错误&#xff0c;少了Collection这一列云云。 【分析】 两个环境ChromaDb的版本不同&#xff0c;所以怀疑是…...

Pinocchio: 刚体动力学算法库介绍

Pinocchio 是一个高性能的开源刚体动力学计算库&#xff0c;广泛应用于机器人学研究与开发。它主要致力于提供高效、精确的运动学和动力学算法&#xff0c;实现机器人模型的建模、前向运动学、反向动力学、力动力学计算等功能。下面将详细介绍该库的一些关键特点和应用场景。 基…...

电商平台的设计与实现(代码+数据库+LW)

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统商品交易信息管理难度大&#xff0c;容错率低&#xff0…...

c#对接deepseek 聊天AI接口

注意&#xff1a;不是免费 对接文档&#xff1a;对话补全 | DeepSeek API Docs 注册地址&#xff1a;DeepSeek 申请key 在线请求示例 apifox deepseek - deepseek...

Node.js中http模块(二)

一、http模块 http 模块是 Node.js 官方提供的、用来创建 web 服务器的模块。通过 http 模块提供的 http.createServer0) 方法&#xff0c;就能方便的把一台普通的电脑&#xff0c;变成一台 Web 服务器&#xff0c;从而对外提供 Web 资源服务。 二、域名和域名服务器 尽管 I…...

主流顶级域名服务商ZDNS连续十余年跟进国际顶级域名政策制定

顶级域名(TLD,Top-Level Domain)是域名层次结构中的最高层,位于域名最后一段,也即最右边的点(.)之后的字符。品牌顶级域名是顶级域名的一种,以品牌相关名称命名,由品牌所属企业申请、运营、并自由分配二级域名,能够直接反映企业或品牌的形象和特色,如.citic、.中信、.baidu、.联…...

低至3折,百度智能云千帆宣布全面支持DeepSeek-R1/V3调用

DeepSeek-R1和 DeepSeek-V3模型已在百度智能云千帆平台上架 。 出品|产业家 新年伊始&#xff0c;百度智能云又传来新动作 。 2月3日百度智能云宣布&#xff0c; DeepSeek-R1和 DeepSeek-V3模型已在百度智能云千帆平台上架&#xff0c;同步推出超低价格方案&#xff0c;并…...

解释一下数据库中的事务隔离级别,在 Java 中如何通过 JDBC设置事务隔离级别?

数据库中的事务隔离级别是用于控制并发事务之间相互影响的一种机制。 它定义了事务之间的可见性和影响范围&#xff0c;常见的隔离级别包括&#xff1a; 读未提交&#xff08;Read Uncommitted&#xff09;&#xff1a;最低的隔离级别&#xff0c;事务中的修改即使没有提交也…...

【自动化测试】使用Python selenium类库模拟手人工操作网页

使用Python selenium类库模拟手人工操作网页 背景准备工作安装Python版本安装selenium类库下载selenium驱动配置本地环境变量 自动化脚本输出页面表单自动化填充相关代码 背景 待操作网页必须使用IE浏览器登录访问用户本地只有edge浏览器&#xff0c;通过edge浏览器IE模式访问…...

SDMatte提示词库共建:分享与收集高效抠图的魔法指令

SDMatte提示词库共建&#xff1a;分享与收集高效抠图的魔法指令 1. 为什么需要提示词库 抠图是设计工作中最常见的需求之一&#xff0c;但每次都要从头开始描述需求既费时又低效。这就好比每次做饭都要从认识食材开始&#xff0c;而不是直接使用现成的菜谱。SDMatte作为智能抠…...

OpenClaw与Qwen3-VL:30B:高效个人AI办公助手实战

OpenClaw与Qwen3-VL:30B&#xff1a;高效个人AI办公助手实战 1. 为什么选择OpenClawQwen3-VL组合 去年冬天&#xff0c;当我第5次因为会议记录整理到凌晨两点时&#xff0c;终于决定寻找自动化解决方案。在尝试了市面上各种RPA工具后&#xff0c;偶然发现了OpenClaw这个开源框…...

LabelImg图像标注工具:3分钟掌握高效目标检测数据标注技巧

LabelImg图像标注工具&#xff1a;3分钟掌握高效目标检测数据标注技巧 【免费下载链接】labelImg LabelImg is now part of the Label Studio community. The popular image annotation tool created by Tzutalin is no longer actively being developed, but you can check ou…...

WDMHDA:Windows 旧系统高清音频驱动的突破与挑战

【导语&#xff1a;WDMHDA 是一款适用于 Windows 98SE / ME 的高清音频驱动程序&#xff0c;为旧系统的音频功能带来新可能。但目前处于 Alpha 阶段&#xff0c;存在诸多待解决问题&#xff0c;其发展对旧系统音频生态有重要影响。】WDMHDA&#xff1a;旧系统音频驱动新选择WDM…...

Vivado实战:从零封装自定义接口IP核的完整流程

1. 为什么需要封装自定义IP核 第一次接触FPGA开发时&#xff0c;我总喜欢把整个工程的所有代码都堆在一个项目里。直到某天需要复用之前的HDMI显示模块时&#xff0c;才发现要手动复制几十个文件&#xff0c;还得逐个修改端口连接。这种重复劳动让我意识到&#xff1a;封装IP核…...

RAGFlow图片回答避坑指南:为什么不用Base64和阿里云OSS?

RAGFlow图片回答架构设计&#xff1a;从Base64到容器化服务器的技术演进 当RAG系统需要处理包含图片的回答时&#xff0c;技术选型直接关系到系统的性能、安全性和可维护性。本文将深入探讨几种主流方案的优劣对比&#xff0c;并解析为何容器化图片服务器成为当前最优解。 1. 图…...

Pixel Dream Workshop 在电商领域的应用:一键生成商品场景图

Pixel Dream Workshop 在电商领域的应用&#xff1a;一键生成商品场景图 1. 电商商品图的痛点与机遇 电商行业有个公开的秘密&#xff1a;商品图片的制作成本往往比想象中高得多。我们曾合作过的一家服装电商&#xff0c;每月仅模特拍摄费用就超过20万元&#xff0c;这还不包…...

Notepad4:轻量级编辑器的技术突破与实用指南

Notepad4&#xff1a;轻量级编辑器的技术突破与实用指南 【免费下载链接】notepad2 Notepad2-zufuliu is a light-weight Scintilla based text editor for Windows with syntax highlighting, code folding, auto-completion and API list for many programming languages and…...

Magika:AI驱动的文件类型检测神器,准确率高达99%+

Magika&#xff1a;AI驱动的文件类型检测神器&#xff0c;准确率高达99% 【免费下载链接】magika 项目地址: https://gitcode.com/GitHub_Trending/ma/magika 你是否曾经遇到过这样的情况&#xff1a;下载了一个文件却不知道它是什么格式&#xff1f;或者在处理大量文件…...

Unity坐标系实战解析:从localPosition到Position的层级关系与应用场景

1. 理解Unity中的坐标系基础 在Unity开发中&#xff0c;坐标系系统是构建3D世界的基石。很多新手开发者容易混淆localPosition和Position的概念&#xff0c;导致物体位置控制出现各种"灵异现象"。我们先从一个生活场景来理解&#xff1a;想象你站在客厅里&#xff08…...