如何为Odin项目计算器实现多步运算链式功能?
实现计算器多步链式运算解决方案
我帮你搞定多步链式运算的问题!先梳理下现有代码的核心局限:当前逻辑只支持「输入左数→点运算符→输入右数→点等号」的单次运算,运算结果没有被保留作为下一次运算的起始值,而且连续点击运算符时也没有处理覆盖或延续的逻辑。
下面是修改后的完整代码,我保留了你原有的注释风格,同时调整了核心逻辑:
let Display_ = document.getElementById('display'); // 用于显示所有点击的数字的显示屏。 // 算术运算函数:改为只返回计算结果,不直接修改显示屏,让逻辑更解耦 function add(a, b) { return parseFloat(a) + parseFloat(b); } function sub(a, b) { return parseFloat(a) - parseFloat(b); } function mul(a, b) { return parseFloat(a) * parseFloat(b); } function div(a, b) { // 新增除零判断,避免控制台报错 if (parseFloat(b) === 0) { return "Error"; } return parseFloat(a) / parseFloat(b); } // operate函数:根据运算符调用对应运算,返回计算结果 function operate(operator, a, b) { switch(operator) { case "+": return add(a, b); case "-": return sub(a, b); case "*": return mul(a, b); case "÷": return div(a, b); default: return b; // 无有效运算符时,直接返回右操作数 } } // 状态变量调整:新增标记和细分操作数存储,支持链式运算 let currentOperand = ''; // 当前显示屏上的输入内容 let previousOperand = ''; // 上一次运算的左操作数或最终结果 let currentOperator = null; // 当前选中的运算符 let isCalculated = false; // 标记是否刚完成一次运算,用于处理运算后的输入逻辑 let NUMBERS = document.querySelectorAll('.n'); // 选中所有带数值的按钮 NUMBERS.forEach((n) => { n.addEventListener('click', function () { // 如果刚完成计算,点击数字时清空显示屏,开始新的输入 if (isCalculated) { Display_.textContent = ''; isCalculated = false; } // 避免重复输入小数点 if (n.textContent === '.' && Display_.textContent.includes('.')) return; Display_.textContent += n.textContent; currentOperand = Display_.textContent; }) }) let CLEAR = document.getElementById('clear'); // 获取清除按钮 CLEAR.addEventListener('click', function () { Display_.textContent = ''; currentOperand = ''; previousOperand = ''; currentOperator = null; isCalculated = false; }) let OPERATORS = document.querySelectorAll('.operator'); // 获取除等号外的所有运算符按钮 OPERATORS.forEach((o) => { o.addEventListener('click', function () { // 如果已有运算符且输入了右操作数,先完成上一次运算 if (currentOperator && currentOperand) { const result = operate(currentOperator, previousOperand, currentOperand); Display_.textContent = result; previousOperand = result; currentOperand = ''; } // 还没输入任何数字时,点击运算符不做操作(优化体验) else if (!currentOperand && !previousOperand) { return; } // 刚完成计算时,直接把结果作为下一次的左操作数 else if (isCalculated) { isCalculated = false; } // 首次点击运算符,把当前输入存为左操作数 else { previousOperand = currentOperand; currentOperand = ''; } // 更新当前选中的运算符,清空显示屏准备输入右操作数 currentOperator = o.textContent; Display_.textContent = ''; }) }) let EQUAL = document.getElementById('equal'); // 获取等号按钮。 EQUAL.addEventListener('click', function () { // 没有运算符或未输入右操作数时,不执行运算 if (!currentOperator || !currentOperand) return; const result = operate(currentOperator, previousOperand, currentOperand); Display_.textContent = result; // 把运算结果存为previousOperand,支持下一次链式运算 previousOperand = result; currentOperand = ''; currentOperator = null; isCalculated = true; // 标记已完成计算,方便后续输入处理 })
关键改动说明:
- 解耦运算与显示:原来的运算函数直接修改显示屏,现在改成返回计算结果,逻辑更清晰,也方便结果复用。
- 完善状态管理:用
previousOperand存储上一次的结果或左操作数,currentOperand存当前输入,currentOperator存选中的运算符,isCalculated标记是否刚完成计算,处理运算后的输入逻辑。 - 连续运算符处理:用户连续点击运算符时(比如
1+2*3),会先完成上一次运算(1+2=3),再把结果作为下一次的左操作数,继续后续运算。 - 细节体验优化:新增除零错误提示、防止重复输入小数点、空输入时点击运算符无反应等细节处理。
这样修改后,你的计算器就支持链式运算了,比如可以连续执行10+5*2=得到20,或者20÷4+3=得到8这类多步操作。
内容的提问来源于stack exchange,提问作者okerrrrrrrr
相关产品推荐
相关产品推荐

