JavaScript中的迭代器协议和可迭代对象是一套用于统一数据遍历方式的规范,只要对象符合可迭代协议,就可以使用for...of循环、扩展运算符等方式进行遍历,不需要关心对象内部的数据结构。实现这套协议需要遵循特定的规则,下面逐步讲解具体的实现方法。

迭代器协议的核心规则
迭代器协议要求对象必须实现一个next()方法,该方法返回一个包含done和value两个属性的对象:
done是布尔值,当迭代完成时返回true,未完成时返回falsevalue是当前迭代步骤返回的值,当done为true时,value可以省略
下面是一个最基础的迭代器实现示例:
// 基础迭代器实现
function createIterator(arr) {
let index = 0;
return {
next: function() {
if (index < arr.length) {
return { done: false, value: arr[index++] };
} else {
return { done: true };
}
}
};
}
const iterator = createIterator([1, 2, 3]);
console.log(iterator.next()); // { done: false, value: 1 }
console.log(iterator.next()); // { done: false, value: 2 }
console.log(iterator.next()); // { done: false, value: 3 }
console.log(iterator.next()); // { done: true }
可迭代对象的实现要求
可迭代对象需要满足可迭代协议,也就是对象上必须有一个Symbol.iterator属性,该属性的值是一个函数,调用该函数会返回一个符合迭代器协议的对象。常见的数组、字符串、Map、Set都是内置的可迭代对象,我们也可以自定义可迭代对象。
自定义可迭代对象的基本结构如下:
const iterableObj = {
// 必须实现Symbol.iterator方法
[Symbol.iterator]: function() {
// 返回符合迭代器协议的对象
return {
next: function() {
// 迭代逻辑
}
};
}
};
完整自定义可迭代对象示例
我们来实现一个自定义的范围迭代器,能够遍历从起始值到结束值的所有整数,包含起始值不包含结束值:
// 自定义范围可迭代对象
const range = {
start: 1,
end: 5,
// 实现Symbol.iterator方法
[Symbol.iterator]: function() {
let current = this.start;
const end = this.end;
// 返回迭代器对象
return {
next: function() {
if (current < end) {
return { done: false, value: current++ };
} else {
return { done: true };
}
}
};
}
};
// 使用for...of遍历
for (const num of range) {
console.log(num); // 依次输出1、2、3、4
}
// 使用扩展运算符
const arr = [...range];
console.log(arr); // [1, 2, 3, 4]
迭代器的特性说明
迭代器是一次性的,遍历完成后再次调用next()方法只会返回{ done: true },无法重新开始遍历。如果需要多次遍历同一个可迭代对象,可以在Symbol.iterator方法中每次返回新的迭代器实例:
const reusableRange = {
start: 1,
end: 4,
[Symbol.iterator]: function() {
// 每次调用都返回新的迭代器,支持多次遍历
let current = this.start;
const end = this.end;
return {
next: function() {
if (current < end) {
return { done: false, value: current++ };
}
return { done: true };
}
};
}
};
console.log([...reusableRange]); // [1,2,3]
console.log([...reusableRange]); // [1,2,3],可以再次遍历
常见注意事项
Symbol.iterator是固定的属性名,不能拼写错误,否则对象不会被识别为可迭代对象- 迭代器的
next()方法内部的this指向需要注意,如果使用箭头函数定义next,this会指向外层作用域,可能导致无法访问到对象自身的属性 - 普通对象默认不是可迭代对象,如果没有实现
Symbol.iterator方法,使用for...of遍历会直接报错
通过上面的示例可以看出,实现可迭代对象和迭代器协议的核心是遵循两个协议的要求,只要满足Symbol.iterator属性和next()方法的规范,就可以让自定义对象支持统一的遍历方式,提升代码的通用性。
JavaScript迭代器可迭代对象迭代器协议for_of修改时间:2026-06-17 17:06:30