闭包实现计数器的核心是外层函数返回内层函数并捕获其局部变量,每次调用工厂函数创建独立作用域,确保各实例的count互不干扰;增强版可返回含increment、decrement、reset、value方法的对象以安全操作私有状态。

用闭包实现计数器,核心是让每次调用函数都生成一个独立的私有变量(如 count),不互相干扰。关键在于:外层函数返回内层函数,内层函数引用外层的局部变量,从而“捕获”并持续维护该变量。
基础写法:单个独立计数器
下面是一个最简实现:
<script></script>
function createCounter() {
let count = 0;
return function() {
count++;
return count;
};
}
const counter1 = createCounter();
console.log(counter1()); // 1
console.log(counter1()); // 2
这里 counter1 是 createCounter() 返回的函数,它记住了自己那一份 count,后续调用不会影响其他计数器。
多个计数器互不干扰
每次调用 createCounter() 都会新建一个作用域,因此可安全创建多个实例:
立即学习“Java免费学习笔记(深入)”;
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
-
const a = createCounter();→ 拥有独立的count(初始为 0) -
const b = createCounter();→ 另一份独立的count(也从 0 开始) -
a()和b()完全无关,各自递增、互不影响
这是闭包保持状态的本质:**每个闭包实例绑定自己的词法环境**。
增强版:支持重置和读取当前值
实际中常需要更多操作,可以返回一个对象,暴露多个方法:
<script></script>
function createCounter() {
let count = 0;
return {
increment() { return ++count; },
decrement() { return --count; },
reset() { count = 0; },
value() { return count; }
};
}
const c1 = createCounter();
c1.increment(); // 1
c1.increment(); // 2
console.log(c1.value()); // 2
这样既保持了状态私有性(count 无法从外部直接访问),又提供了清晰的接口。
注意点:避免意外共享
常见错误是把变量声明在闭包外部,导致多个实例共用同一份数据:
❌ 错误示例(不要这样写):
let sharedCount = 0;
function badCounter() {
return function() { return ++sharedCount; }; // 所有调用共享同一个 sharedCount
}
务必确保状态变量(如 count)定义在工厂函数内部,且每次调用都重新声明。

















