JavaScript中的迭代器协议与可迭代对象
字数 874 2025-11-15 07:12:20
JavaScript中的迭代器协议与可迭代对象
描述
迭代器协议(Iterator Protocol)是ES6引入的一种标准机制,用于定义如何遍历数据集合中的元素。任何对象只要实现了特定的next()方法,就被认为是一个迭代器。而可迭代对象(Iterable)则实现了@@iterator方法(通过Symbol.iterator键访问),该方法返回一个迭代器。常见的可迭代对象包括数组、字符串、Map、Set等。
1. 迭代器的基本结构
一个迭代器必须实现next()方法,该方法返回一个包含两个属性的对象:
value:当前迭代的值(若迭代完毕则为undefined)。done:布尔值,表示迭代是否完成。
示例:
const simpleIterator = {
next() {
return { value: 1, done: false }; // 永远返回1,永不结束(实际需控制结束条件)
}
};
2. 实现一个自定义迭代器
假设要遍历一个数字范围(如1到3),需通过闭包保存当前状态:
function createRangeIterator(start, end) {
let current = start;
return {
next() {
if (current <= end) {
return { value: current++, done: false };
}
return { value: undefined, done: true };
}
};
}
const iterator = createRangeIterator(1, 3);
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
3. 可迭代对象的定义
若对象具有Symbol.iterator方法,且该方法返回一个迭代器,则该对象是可迭代的。可迭代对象可用于for...of循环、展开运算符(...)等场景。
示例:自定义一个可迭代的“数字范围”对象:
const range = {
from: 1,
to: 3,
[Symbol.iterator]() {
let current = this.from;
return {
next: () => { // 使用箭头函数绑定`this`以访问`from`/`to`
if (current <= this.to) {
return { value: current++, done: false };
}
return { value: undefined, done: true };
}
};
}
};
// 使用for...of遍历
for (const num of range) {
console.log(num); // 依次输出1, 2, 3
}
// 使用展开运算符
console.log([...range]); // [1, 2, 3]
4. 内置可迭代对象的迭代器
数组、字符串等内置可迭代对象可直接通过Symbol.iterator获取迭代器:
const arr = [10, 20];
const arrIterator = arr[Symbol.iterator]();
console.log(arrIterator.next()); // { value: 10, done: false }
const str = "hi";
const strIterator = str[Symbol.iterator]();
console.log(strIterator.next()); // { value: 'h', done: false }
5. 迭代协议的应用场景
for...of循环:仅适用于可迭代对象。- 解构赋值:如
const [a, b] = range;。 Array.from():将可迭代对象转为数组。- Map/Set的构造函数:
new Set(range)。
6. 与生成器(Generator)的关系
生成器函数(function*)返回的生成器对象既是迭代器,也是可迭代对象,可简化迭代器实现:
const range = {
from: 1,
to: 3,
*[Symbol.iterator]() { // 生成器方法
for (let i = this.from; i <= this.to; i++) yield i;
}
};
console.log([...range]); // [1, 2, 3]
总结
迭代器协议通过标准化遍历行为,使不同数据结构(如自定义对象与内置集合)能统一被遍历。理解迭代器与可迭代对象的区别(迭代器实现next(),可迭代对象实现Symbol.iterator)是关键。实际开发中,生成器常用来快速创建迭代器。