闭包实现计数器的核心是利用函数作用域私有保存count变量,仅通过返回的函数接口操作;每次调用createcounter()生成独立闭包,互不干扰;增强版支持初始化、增减、获取、重置等方法,确保状态封装安全。

用闭包实现计数器,核心是利用函数作用域“记住”外部变量,让计数状态不被外部直接修改,同时提供可控的访问接口。
闭包计数器的基本写法
定义一个外层函数(比如 createCounter),它返回一个内层函数。内层函数访问并修改外层函数中声明的变量(如 count),这个变量就形成了私有状态:
function createCounter() {
let count = 0;
return function() {
count++;
return count;
};
}
const counter1 = createCounter();
console.log(counter1()); // 1
console.log(counter1()); // 2
console.log(counter1()); // 3
每次调用 createCounter() 都会生成独立的闭包环境,所以 counter1 和另一个 counter2 互不影响。
支持初始化值和多种操作的增强版
可以扩展为支持初始值、递增、递减、获取当前值等方法,仍保持内部状态私有:
function createCounter(initial = 0) {
let count = initial;
return {
increment: () => ++count,
decrement: () => --count,
value: () => count,
reset: () => count = initial
};
}
const counter = createCounter(10);
console.log(counter.value()); // 10
console.log(counter.increment()); // 11
console.log(counter.decrement()); // 10
counter.reset();
console.log(counter.value()); // 10
为什么必须用闭包?普通函数不行吗?
如果直接用全局变量或对象属性存 count,状态就暴露在外,容易被意外修改:
- 全局变量:所有地方都能改,污染全局、不可靠
- 对象属性:虽然封装了,但 counter.count = 999 这种赋值仍可绕过逻辑
- 闭包:count 只在函数作用域内存在,外部无法直接访问或赋值,只能通过你提供的函数操作
常见误区提醒
- 不要在循环中直接创建闭包计数器却复用同一个变量(比如 for 循环里用 var 声明 i)——容易捕获到最终值,建议用 let 或明确传参
- 闭包本身不会自动“记忆”多次调用;它的记忆能力来自函数定义时所处的作用域链,不是魔法
- 每个闭包实例独享一份变量,不是共享同一份 count
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











