for...of循环可遍历任何实现迭代协议的对象,关键在于其必须提供返回迭代器的[symbol.iterator]()方法;该迭代器需有next()方法,每次返回{value, done}对象;自定义时须确保每次调用[symbol.iterator]()都返回新迭代器。

JavaScript 中,for...of 循环能自动消费任何实现了 迭代协议(iteration protocol) 的对象,关键在于该对象必须提供一个符合规范的 [Symbol.iterator]() 方法,返回一个迭代器(iterator)对象。自定义可迭代对象时,只需正确实现这个方法即可。
1. 理解迭代器协议的核心结构
一个“可迭代对象”需满足:
- 拥有
[Symbol.iterator]方法(即键为Symbol.iterator的函数) - 该方法返回一个“迭代器对象”,该对象必须有
next()方法 -
next()每次调用返回形如{ value: ..., done: true|false }的对象
2. 手动实现一个简单可迭代对象
例如,创建一个表示前 n 个自然数的可迭代类:
class Countdown {
constructor(n) {
this.n = n;
}
<p>[Symbol.iterator]() {
let i = this.n;
return {
next() {
if (i > 0) {
return { value: i--, done: false };
} else {
return { value: undefined, done: true };
}
}
};
}
}</p><p>// 使用 for...of
for (const num of new Countdown(3)) {
console.log(num); // 输出: 3, 2, 1
}</p>
3. 更实用:让普通对象或数组-like 结构可迭代
比如封装一组数据并控制遍历行为(跳过 null/undefined、做转换等):
const data = [1, null, 2, undefined, 3];
<p>const filteredIterable = {
[Symbol.iterator]() {
const arr = data.filter(x => x != null);
let index = 0;
return {
next() {
if (index </p><p>for (const v of filteredIterable) {
console.log(v); // 输出: 2, 4, 6
}</p>
4. 注意事项与常见陷阱
确保每次调用 [Symbol.iterator]() 都返回**新迭代器**,否则多次遍历会相互干扰:
- ❌ 错误:复用同一个迭代器对象(导致第二次
for...of立即结束) - ✅ 正确:每次调用都新建闭包或状态对象(如上面例子中在方法内声明
let i = ...) - 迭代器应是“惰性”的——
next()被调用时才计算下一个值 -
done: true后,后续next()调用仍应返回{ value: undefined, done: true }
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











