定义迭代器
想象我们去图书馆借书,管理员(迭代器)按顺序从书架上取书给到我们
- 我们不需要知道书架结构(数组、字符串、Map 等内部细节)
- 只需说"下一本" (调用
next()
方法) - 管理员返回书和状态 (
{ value: 书, done: 是否取完 }
)
js
const books = ["📖JS指南", "📚CSS揭秘"];
const librarian = books[Symbol.iterator](); // 找管理员
console.log(librarian.next()); // { value: "📖JS指南", done: false }
console.log(librarian.next()); // { value: "📚CSS揭秘", done: false }
console.log(librarian.next()); // { value: undefined, done: true }(书已取完)
为啥要迭代器
统一遍历方式
不同数据结构(数组、字符串、Map等)都通过相同的接口 (Symbol.iterator
)提供迭代器,无需再记不同遍历方法
js
// 数组、字符串、Set 都能用同一姿势遍历
for (const item of [1, 2, 3]) { /*...*/ } // 数组
for (const char of "Hi") { /*...*/ } // 字符串
for (const entry of new Set([10, 20])) { /*...*/ } // Set
按需取值,节省内存 迭代器懒加载 特性:只有调用 next()
时才计算下一个值,适合处理大规模数据(如日志文件)
那要怎么使用
-
创建迭代器 :通过
[Symbol.iterator]()
方法获取 -
遍历三步曲:
- 调用
next()
- 返回
{ value: 当前值, done: 是否结束 }
- 若
done=true
则停止
- 调用
ES6中哪些数据自带迭代器
数据类型 | 示例 | 遍历内容 |
---|---|---|
数组 Array |
[1, 2] |
元素值(1, 2) |
字符串 String |
"AB" |
字符("A", "B") |
集合 Set |
new Set([10, 20]) |
元素值(10, 20) |
字典 Map |
new Map([["key", "value"]]) |
键值对(["key", "value"]) |
类数组 arguments |
function fn() { for (x of arguments) } |
函数参数值 |
迭代器 vs for...of
循环
- 迭代器 :底层协议(
next()
方法) for...of
:基于迭代器的语法糖,自动处理遍历
js
// for...of 内部等效代码
const it = books[Symbol.iterator]();
let result = it.next();
while (!result.done) {
const book = result.value;
console.log(book);
result = it.next();
}
牢记
迭代器如同数据世界的通用遥控器,让不同数据结构用相同方式访问,让处理大数据流变得高效,让复杂遍历变得简单可控