ES6 迭代器 (`Iterator`)使用总结
Iterator
(迭代器)是 ES6 引入的一种 接口,用于 顺序访问 可迭代对象(Array
、Set
、Map
、String
、arguments
、自定义对象等)。
Iterator(迭代器)的作用有三个:
- 为各种数据结构提供一个统一的、简便的访问接口
- 使数据结构的成员能够按某种次序排列
- 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
所有 可迭代对象(Array
、Set
、Map
等)都有 默认的迭代器,可以用 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
可与 break
、continue
配合使用。
4. 可迭代对象
✅ 可以使用 for...of
、Symbol.iterator
的对象
Array
String
Set
Map
arguments
NodeList
- 自定义对象(需实现
Symbol.iterator
)
5. Set
和 Map
的迭代器
(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. 适用场景
✅ 适用于
- 遍历数组、字符串、Set、Map
- 自定义可迭代对象
- 流式处理数据(类似分页加载)
- 避免一次性加载大数据(生成器)
11. 总结
Iterator
是 ES6 提供的一种接口,用于顺序访问集合。Symbol.iterator
让对象变成可迭代,可用于for...of
、spread
。Set
、Map
、Array
、String
默认实现Symbol.iterator
,可直接迭代。- 生成器 (
Generator
) 自动创建迭代器,可暂停执行 (yield
),更强大。
相关文章:
ES6 迭代器 (`Iterator`)使用总结
Iterator(迭代器)是 ES6 引入的一种 接口,用于 顺序访问 可迭代对象(Array、Set、Map、String、arguments、自定义对象等)。 Iterator(迭代器)的作用有三个: 为各种数据结构提供一个…...

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

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

[论文阅读] Knowledge Fusion of Large Language Models
Knowledge Fusion of Large Language Models (FuseLLM) Methodology 整体Pipeline如下图所示 不同的动物代表不同的LLM。左边第一,第二分别是Ensemble以及Weight Merging方法。最右侧为本文提出的FuseLLM。 Ensemble: 融合多个models的预测结果,比如…...
deepseek来讲lua
Lua 是一种轻量级、高效、可嵌入的脚本语言,广泛应用于游戏开发、嵌入式系统、Web 服务器等领域。以下是 Lua 的主要特点和一些基本概念: 1. 特点 轻量级:Lua 的核心非常小,适合嵌入到其他应用程序中。高效:Lua 的执…...
探索 Spring Cloud Alibaba:开启微服务架构新时代
一、引言 在当今数字化浪潮中,软件系统的规模和复杂度不断攀升,传统的单体架构逐渐难以满足快速迭代、高并发处理以及灵活扩展的需求。微服务架构应运而生,它将一个大型的应用拆分成多个小型、自治的服务,每个服务专注于特定的业务…...

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

【工具变量】上市公司企业渐进式创新程度及渐进式创新锁定数据(1991-2023年)
测算方式: 参考顶刊《经济研究》孙雅慧(2024)老师的做法,用当期创新和往期创新的内容重叠度作为衡量渐进式创新程度的合理指标。通过搜集海量专利摘要,测算当前专利申请和既有专利的内容相似度,反映企业在…...

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

【R语言】apply函数族
在R语言中使用循环操作时是使用自身来实现的,效率较低。所以R语言有一个符合其统计语言出身的特点:向量化。R语言中的向量化运用了底层的C语言,而C语言的效率比高层的R语言的效率高。 apply函数族主要是为了解决数据向量化运算的问题&#x…...
Retrieval-Augmented Generation,检索增强生成流程
RAG流程 用户输入接收 系统接收用户输入的查询问题或文本内容,例如“李白有哪些著名的作品?”用户输入可以通过自然语言处理(NLP)模型的输入端口或用户交互界面(如聊天应用、搜索引擎输入框等)接收。 查询…...
[AI][本地部署]离线升级后报ChromeDb错误
【背景】 升级了OpenWebUI,在离线环境下补足了很多需要的Package后终于成功启动了Backend的服务,但是一旦上传文件,就会报ChromaDb错误,少了Collection这一列云云。 【分析】 两个环境ChromaDb的版本不同,所以怀疑是…...
Pinocchio: 刚体动力学算法库介绍
Pinocchio 是一个高性能的开源刚体动力学计算库,广泛应用于机器人学研究与开发。它主要致力于提供高效、精确的运动学和动力学算法,实现机器人模型的建模、前向运动学、反向动力学、力动力学计算等功能。下面将详细介绍该库的一些关键特点和应用场景。 基…...

电商平台的设计与实现(代码+数据库+LW)
摘 要 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术的弊端问题。因为传统商品交易信息管理难度大,容错率低࿰…...

c#对接deepseek 聊天AI接口
注意:不是免费 对接文档:对话补全 | DeepSeek API Docs 注册地址:DeepSeek 申请key 在线请求示例 apifox deepseek - deepseek...
Node.js中http模块(二)
一、http模块 http 模块是 Node.js 官方提供的、用来创建 web 服务器的模块。通过 http 模块提供的 http.createServer0) 方法,就能方便的把一台普通的电脑,变成一台 Web 服务器,从而对外提供 Web 资源服务。 二、域名和域名服务器 尽管 I…...
主流顶级域名服务商ZDNS连续十余年跟进国际顶级域名政策制定
顶级域名(TLD,Top-Level Domain)是域名层次结构中的最高层,位于域名最后一段,也即最右边的点(.)之后的字符。品牌顶级域名是顶级域名的一种,以品牌相关名称命名,由品牌所属企业申请、运营、并自由分配二级域名,能够直接反映企业或品牌的形象和特色,如.citic、.中信、.baidu、.联…...

低至3折,百度智能云千帆宣布全面支持DeepSeek-R1/V3调用
DeepSeek-R1和 DeepSeek-V3模型已在百度智能云千帆平台上架 。 出品|产业家 新年伊始,百度智能云又传来新动作 。 2月3日百度智能云宣布, DeepSeek-R1和 DeepSeek-V3模型已在百度智能云千帆平台上架,同步推出超低价格方案,并…...
解释一下数据库中的事务隔离级别,在 Java 中如何通过 JDBC设置事务隔离级别?
数据库中的事务隔离级别是用于控制并发事务之间相互影响的一种机制。 它定义了事务之间的可见性和影响范围,常见的隔离级别包括: 读未提交(Read Uncommitted):最低的隔离级别,事务中的修改即使没有提交也…...

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

Android之ListView
1:简单列表(ArrayAdapter) 1:运行的结果: 2:首先在MyListView里面创建一个按钮,点击的时候进行跳转。 这里让我吃惊的是,Button里面可以直接设置onClick .java里面的方法。 也即是点击这个按钮之后就会去…...

JS和TS的区别
JavaScript 与 TypeScript 的主要区别和特性对比 1. 基础定义 JavaScript 是一种动态、弱类型的编程语言,广泛应用于前端开发以及通过 Node.js 扩展到后端开发。TypeScript 则是 JavaScript 的超集,它在 JavaScript 的基础上添加了静态类型系统和其他增…...

【Qt】Bug:findChildren找不到控件
使用正确的父对象调用 findChildren:不要在布局对象上调用 findChildren,而应该在布局所在的窗口或控件上调用。...
Femap许可证与网络安全策略
随着科技的快速发展,网络安全问题已成为各行各业关注的焦点。在电磁仿真领域,Femap作为一款领先的软件,其许可证的安全性和网络策略的重要性不言而喻。本文将探讨Femap许可证与网络安全策略的关系,确保您的电磁仿真工作能够在一个…...

基于CangjieMagic的RAG技术赋能智能问答系统
目录 引言 示例程序分析 代码结构剖析 导入模块解读 智能体配置详情 提示词模板说明 主程序功能解析 异步聊天功能实现 检索信息展示 技术要点总结 ollama 本地部署nomic-embed-text 运行测试 结语 引言 这段时间一直在学习CangjieMagic。前几天完成了在CangjieMa…...

10.安卓逆向2-frida hook技术-frida基本使用-frida指令(用于hook)
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 内容参考于:图灵Python学院 工具下载: 链接:https://pan.baidu.com/s/1bb8NhJc9eTuLzQr39lF55Q?pwdzy89 提取码࿱…...

Acrobat DC v25.001 最新专业版已破,像word一样编辑PDF!
在数字化时代,PDF文件以其稳定性和通用性成为了文档交流和存储的热门选择。无论是阅读、编辑、转换还是转曲,大家对PDF文件的操作需求日益增加。因此,一款出色的PDF处理软件不仅要满足多样化的需求,还要通过简洁的界面和强大的功能…...
基于RK3588的智慧农场系统开发|RS485总线|华为云IOT|node-red|MQTT
一、硬件连接流程 本次采用的是 总线型拓扑:所有设备并联到两根 RS485 总线上(A 和 B-) 二、通信协议配置 1. 主从通信模式 RS485 是半双工:同一时间只能有一个设备发送数据主从架构:通常一个主设备(…...

【面试 - 遇到的问题 - 优化 - 地图】腾讯地图轨迹回放 - 回放的轨迹时间要和现实时间对应(非匀速)
目录 背景轨迹回放 - 匀速效果图TrackPlaybackDialog.vue 代码TMapNew.vue 代码 轨迹回放 - 非匀速效果图TrackPlaybackDialog.vue 代码TMapNew.vue 代码 背景 腾讯地图轨迹回放是匀速回放的,但是客户要求根据现实时间,什么时间点在某个点位 【腾讯地图轨…...

【Rust模式与匹配】Rust模式与匹配深入探索与应用实战
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…...