闭包实现的计算器通过私有变量state和history数组封装状态与历史快照,暴露add、subtract、undo等接口;每次运算前保存state快照,undo直接弹出历史值赋给state,支持防误检查与可选redo功能。

用闭包实现带撤销功能的计算器,核心是把当前状态和历史操作封装在私有作用域里,只暴露必要的操作接口(如输入、计算、撤销),避免外部直接修改内部数据。
闭包封装状态与操作
闭包让计算器的状态(当前值、历史记录栈)不被外部访问,同时提供 add、calculate、undo 等方法。每次调用 calculate 时,把前一个状态压入 history 数组,保证可回溯。
- history 是一个数组,存每次计算前的 state 快照(不是操作本身,而是数值快照)
- state 记录当前结果,初始为 0
- undo 只需弹出 history 最后一项,赋给 state,不执行逆运算,更简单可靠
基础实现示例
下面是一个轻量但完整的闭包计算器:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
function createCalculator() {
let state = 0;
const history = [];
function saveState() {
history.push(state);
}
return {
add: (num) => {
saveState();
state += num;
},
subtract: (num) => {
saveState();
state -= num;
},
multiply: (num) => {
saveState();
state *= num;
},
divide: (num) => {
if (num !== 0) {
saveState();
state /= num;
}
},
undo: () => {
if (history.length > 0) {
state = history.pop();
}
},
getValue: () => state,
getHistoryLength: () => history.length
};
}
// 使用方式:
const calc = createCalculator();
calc.add(5); // state = 5
calc.multiply(2); // state = 10
calc.undo(); // state = 5
console.log(calc.getValue()); // 5
支持连续操作与防误撤销
实际使用中,用户可能连续输入多个数字或运算符,需要区分“操作提交”和“临时输入”。可在闭包内增加 pending 操作缓冲,仅在明确确认(如按 = 或 Enter)时才保存快照。
- 引入 pendingValue 和 pendingOperator,暂存未提交的运算
- 只有调用 calculate 或 clear 后才触发 saveState()
- undo 前检查 history 是否为空,避免静默失败,可返回布尔值提示是否成功
扩展:支持重做(redo)
只需再维护一个 redoStack —— 每次 undo 时把当前 state 推入 redoStack;redo 时从 redoStack 弹出并 push 到 history 尾部(或直接赋值)。注意 redo 后清空 redoStack,防止链式 redo 失控。
- redoStack 初始为空数组
- undo 执行后:redoStack.push(state)
- redo 执行前:if (redoStack.length) { state = redoStack.pop(); }
- 任何新操作(add/subtract等)都要清空 redoStack,符合常规交互逻辑
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










