ES6引入了Iterator(迭代器)接口,用于顺序访问可迭代对象,Iterator接口提供统一的访问接口,并通过for...of循环供消费,本文给大家介绍ES6迭代器Iterator使用总结,感兴趣的朋友跟随小编一起看看吧 ✅可以使用
特性 迭代器 (Iterator) 生成器 (Generator) 创建方式手动实现
目录
1. 迭代器的基本概念(1) 迭代器是什么?2. 生成迭代器(1) 手动创建迭代器(2) 使用 Symbol.iterator(3) 自定义对象的迭代器3. for...of 遍历迭代器4. 可迭代对象✅可以使用for...of、Symbol.iterator的对象5. Set 和 Map 的迭代器6. 迭代器 vs 生成器7. Iterator 使用场景7.1 解构赋值7.2 扩展运算符7.3 yield*8. 注意事项8.1 对象的 for…of 循环8.2 Iterator 接口与 Generator 函数9. 最佳实践9.1 为类部署 Iterator 接口9.2 异步迭代器10. 适用场景11. 总结Iterator
(迭代器)是 ES6 引入的一种 接口,用于 顺序访问 可迭代对象(Array
、Set
、Map
、String
、arguments
、自定义对象等)。
Iterator(迭代器)的作用有三个:
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 生成器
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...oflet 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
),更强大。