getter天然适合延迟初始化generator,因其在首次访问属性时才执行generator函数并返回迭代器,避免实例化时预加载;每次访问可返回新独立迭代器,支持多次互不干扰遍历。

直接在属性声明时用 getter 初始化 Generator,就能实现“首次访问才创建”的延迟效果——无需额外包装类或第三方库,原生语法即可达成。
为什么 Getter 天然适合延迟初始化 Generator
Generator 函数本身不立即执行,只返回一个迭代器对象;而 getter 在每次读取属性时才运行。把两者结合,就自然形成“按需生成、首次调用才构建”的行为:
- Generator 函数体(含
yield)不会在类实例化时运行 - Getter 内部调用
function*并返回其结果,该结果仅在第一次访问属性时产生 - 后续访问复用同一迭代器对象(除非你主动重新生成)
基础写法:用 getter 返回新 Generator 实例
每次访问都获得一个全新、可独立遍历的迭代器(推荐用于需要多次重用、互不干扰的场景):
class DataProcessor {
get items() {
function* generateLargeSequence() {
for (let i = 0; i const processor = new DataProcessor();
console.log(processor.items.next()); // { value: "item-0", done: false }
console.log(processor.items.next()); // { value: "item-0", done: false } ← 新实例,从头开始
进阶写法:getter + 私有缓存,确保单例迭代器
若希望整个实例生命周期内只创建一次 Generator 迭代器(例如连接数据库后只建立一次流),可用私有字段缓存:
class ApiStream {
#iterator = null;
<p>get stream() {
if (!this.#iterator) {
this.#iterator = (function<em> () {
// 模拟耗时初始化:DB 连接、认证、长连接建立
await new Promise(r => setTimeout(r, 200));
yield</em> fetch('/api/events').then(r => r.json());
})();
}
return this.#iterator;
}
}
</p>
注意:此方式下 stream 是惰性求值的单例迭代器,但不可重复遍历(Generator 一旦 done === true 就不可重置)。如需多次消费,应改用数组或 Array.from() 提前展开。
搭配 Symbol.iterator 实现 for...of 友好接口
让类自身可被 for...of 消费,同时保持延迟初始化逻辑:
class LazyRange {
constructor(max) {
this.max = max;
}
<p>get [Symbol.iterator]() {
return function<em> () {
for (let i = 0; i i;
}
}.bind(this);
}
}</em></p><p>const range = new LazyRange(5);
for (const val of range) {
console.log(val); // 0, 1, 4, 9, 16 —— 首次 for...of 触发 generator 创建
}
</p>
这里 [Symbol.iterator] 是 getter,确保迭代器仅在真正遍历时才构建,且每次 for...of 都新建一个干净的 Generator 实例。










