可通过为对象原型添加Symbol.iterator方法使其支持for...of等迭代操作,该方法须返回含next()的迭代器对象,next()需返回{value, done}格式对象。

在 JavaScript 中,可以通过为对象的原型添加 Symbol.iterator 方法,让该类型的所有实例支持 for...of、扩展运算符([...obj])、解构等原生迭代行为。关键在于:这个方法必须返回一个**迭代器对象**(即具有 next() 方法的对象),且 next() 必须返回形如 { value, done } 的对象。
给构造函数原型添加 Symbol.iterator
以自定义类或构造函数为例,比如一个表示数字范围的 Range 类:
// 定义构造函数
function Range(start, end) {
this.start = start;
this.end = end;
}
// 在原型上定义 Symbol.iterator
Range.prototype[Symbol.iterator] = function() {
let current = this.start;
const end = this.end;
// 返回迭代器对象
return {
next() {
if (current
return { value: current++, done: false };
} else {
return { value: undefined, done: true };
}
}
};
};
使用示例与验证
添加后,所有 Range 实例即可被原生迭代语法消费:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
const range = new Range(2, 5);
// for...of
for (const num of range) {
console.log(num); // 输出: 2, 3, 4, 5
}
// 扩展运算符
console.log([...range]); // [2, 3, 4, 5]
// 解构
const [a, b, ...rest] = range;
console.log(a, b, rest); // 2 3 [4, 5]
注意事项和常见陷阱
-
Symbol.iterator方法本身不能是箭头函数,否则this会丢失(箭头函数不绑定this);必须用普通函数或方法简写 - 每次调用
[Symbol.iterator]()都应返回**新的迭代器对象**,避免多个遍历互相干扰(例如两个for...of同时运行) - 如果想让普通对象(非类实例)也支持迭代,可直接在对象字面量上设置:
{ [Symbol.iterator]() { return { next() { return { value: 1, done: true }; } }; } } - 内置类型(如 Array、Map)已自带
Symbol.iterator,重写原型上的该方法会影响所有实例(含已有实例),慎用于内置构造函数(如Array.prototype[Symbol.iterator])
更简洁写法:用生成器函数
ES6+ 支持用 function*(生成器函数)自动返回迭代器,代码更清晰:
立即学习“Java免费学习笔记(深入)”;
Range.prototype[Symbol.iterator] = function*() {
for (let i = this.start; i this.end; i++) {
yield i;
}
};
效果完全一致,且天然满足迭代器协议,推荐优先使用。

















