JavaScript中的迭代器协议与for...of循环
字数 655 2025-11-21 14:49:46
JavaScript中的迭代器协议与for...of循环
描述
迭代器协议是ES6引入的一组规则,定义了如何顺序访问数据集合中的元素。任何对象只要实现了next()方法,就被认为是一个迭代器。for...of循环则是基于迭代器协议的语法糖,能够自动遍历可迭代对象。
核心概念解析
-
可迭代对象(Iterable):
- 必须实现
[Symbol.iterator]()方法,该方法返回一个迭代器对象 - 常见可迭代对象:Array、String、Map、Set、NodeList等
- 必须实现
-
迭代器对象(Iterator):
- 必须实现
next()方法,返回{value: any, done: boolean}形式的对象 - 当
done: true时表示遍历结束
- 必须实现
实现步骤详解
-
基础迭代器实现:
function createCounter(max) { let count = 1 return { next() { if (count <= max) { return { value: count++, done: false } } return { value: undefined, done: true } } } } const counter = createCounter(3) console.log(counter.next()) // {value: 1, done: false} console.log(counter.next()) // {value: 2, done: false} console.log(counter.next()) // {value: 3, done: false} console.log(counter.next()) // {value: undefined, done: true} -
使对象可迭代:
const myIterable = { data: [10, 20, 30], [Symbol.iterator]() { let index = 0 return { next: () => { if (index < this.data.length) { return { value: this.data[index++], done: false } } return { done: true } } } } } // 现在可以用for...of遍历 for (const item of myIterable) { console.log(item) // 依次输出10, 20, 30 } -
生成器简化实现:
const simpleIterable = { *[Symbol.iterator]() { yield 1 yield 2 yield 3 } }
for...of运行机制
- 首先调用对象的
[Symbol.iterator]()方法获取迭代器 - 循环调用迭代器的
next()方法 - 将返回对象的
value属性赋值给循环变量 - 当
done: true时退出循环
与传统遍历对比
- for循环:需要维护索引,适合数组
- for...in:遍历键名,包括原型链属性
- for...of:直接遍历值,更简洁安全
实际应用场景
-
自定义数据结构遍历:
class Range { constructor(start, end) { this.start = start this.end = end } *[Symbol.iterator]() { for (let i = this.start; i <= this.end; i++) { yield i } } } for (const num of new Range(1, 5)) { console.log(num) // 1,2,3,4,5 } -
与解构赋值结合:
const [first, second] = myIterable // first=10, second=20
注意事项
- 迭代器是单向的,遍历后不能重置
- 可迭代对象可以创建多个独立的迭代器
- 手动调用
next()时,最后返回done: true后应继续返回相同结果