闭包与生成器结合可实现惰性求值和状态封装:闭包捕获私有状态并维持上下文,生成器按需yield值;外层函数缓存生成器实例,确保状态延续与受控访问。

闭包与生成器函数结合,能自然实现惰性求值和状态封装——闭包捕获并维持私有状态,生成器则按需产出值、暂停执行,二者配合让逻辑清晰、资源可控。
用闭包保存生成器的私有上下文
生成器函数本身返回迭代器对象,但若每次调用都重新初始化,就丢失了“延续性”。闭包可将生成器实例(或其内部状态)封存在外部作用域中,避免重复创建。
- 定义一个外层函数,内部创建并缓存生成器对象(
const gen = generatorFn()) - 返回一个函数(或对象方法),每次调用时只对这个已存在的生成器执行
next() - 这样,生成器的内部变量(如计数器、缓存数组、上一次计算结果)就被闭包持续持有
惰性求值:只在取值时才计算下一个元素
生成器天然支持惰性:它不会预先计算全部结果,而是在 next() 调用时才运行到下一个 yield。闭包确保这个“暂停-恢复”过程始终基于同一上下文。
- 例如实现一个惰性斐波那契序列:闭包内保存
a和b,每次next()只算下一项,不预生成整个数组 - 再比如读取大文件行:闭包里持有一个文件读取流和当前行号,生成器每次
yield一行,真正触发 I/O 仅在需要时 - 关键点:闭包不让状态暴露,生成器不让计算提前发生
状态控制:通过闭包限制访问与修改权限
你想让外部只能“向前迭代”,不能重置、跳转或篡改中间状态?闭包可以屏蔽生成器对象本身,只暴露受控接口。
- 不直接返回
gen,而是返回{ next(), reset?(), peek?() }等有限方法 - 如果需要重置,可在闭包内提供
reset()方法——它重新调用generatorFn()并替换内部gen引用 - 想支持“预览下一项但不消耗”?闭包里缓存上一次
next()结果,peek()返回缓存值,next()再更新缓存
典型组合写法示例
下面是一个带重置能力的惰性计数器:
const createCounter = (start = 0, step = 1) => {
let gen;
const generator = function* () {
let current = start;
while (true) {
yield current;
current += step;
}
};
<p>const reset = () => { gen = generator(); };
reset(); // 初始化</p><p>return {
next: () => gen.next(),
reset,
[Symbol.iterator]: () => ({ next: () => gen.next() })
};
};</p><p>// 使用
const counter = createCounter(10, 2);
console.log(counter.next().value); // 10
console.log(counter.next().value); // 12
counter.reset();
console.log(counter.next().value); // 10(从头开始)</p>Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











