You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript计算器无法处理多位数计算问题求助

问题:计算器仅支持个位数运算,无法处理多位数
  • 当前问题:所有数字按键会将单个数字存入choices数组,calculate()仅取数组索引0和1的值,导致多位数输入后无法正确计算
  • 需求:支持任意位数的数字运算,禁止使用eval()

原代码

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Calculator</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <h1>Calculator.js</h1>
    <div id="container">
        <div id="input">
            <div class="inputBar"></div>
        </div>
        <div id="buttonList">
            <button id="buttonEquals" class="buttons">=</button>
            <button id="buttonDivide" class="buttons">/</button>
            <button id="buttonMultiply" class="buttons">x</button>
            <button id="buttonSubtract" class="buttons">-</button>
            <button id="buttonAdd" class="buttons">+</button>
            <button id="buttonDot" class="buttons">.</button>
            <button id="buttonDel" class="buttons">C</button>
            <button id="button9" class="buttons">9</button>
            <button id="button5" class="buttons">5</button>
            <button id="button6" class="buttons">6</button>
            <button id="button7" class="buttons">7</button>
            <button id="button8" class="buttons">8</button>
            <button id="button1" class="buttons">1</button>
            <button id="button2" class="buttons">2</button>
            <button id="button3" class="buttons">3</button>
            <button id="button4" class="buttons">4</button>
            <button id="button0" class="buttons">0</button>
        </div>
    </div>
    <div id="darkContainer">
        <button id="darkMode">DARK MODE &#127769;</button>
    </div>
    <h3>Created by Rhys Hodgson as part of The Odin Project.</h3>
</body>
<script src="script.js"></script>
</html>

JavaScript

// calculates the user's choices
function calculate(a, operator, b){
    if (operator === " + ") return a + b;
    else if (operator === " - ") return a - b;
    else if (operator === " * ") return a * b;
    else if (operator === " / ") return a / b;
}

// stores DOM button refs
const buttons = {
    "button0": document.getElementById("button0"),
    "button1": document.getElementById("button1"),
    "button2": document.getElementById("button2"),
    "button3": document.getElementById("button3"),
    "button4": document.getElementById("button4"),
    "button5": document.getElementById("button5"),
    "button6": document.getElementById("button6"),
    "button7": document.getElementById("button7"),
    "button8": document.getElementById("button8"),
    "button9": document.getElementById("button9"),
    "buttonDel": document.getElementById("buttonDel"),
    "buttonDot": document.getElementById("buttonDot"),
    "buttonAdd": document.getElementById("buttonAdd"),
    "buttonSubtract": document.getElementById("buttonSubtract"),
    "buttonMultiply": document.getElementById("buttonMultiply"),
    "buttonDivide": document.getElementById("buttonDivide"),
    "buttonEquals": document.getElementById("buttonEquals"),
}
// stores user button choices
let choices = [];
let operators = [];

// user displayed input
let displayInput = document.querySelector(".inputBar");

// buttons display a string on click, adds number to choices[]
buttons.button0.addEventListener("click", () => {
    displayInput.textContent += "0";
    choices.push(0);
});
buttons.button1.addEventListener("click", () => {
    displayInput.textContent += "1";
    choices.push(1);
    displayInput.style.color = "black";
});
buttons.button2.addEventListener("click", () => {
    displayInput.textContent += "2";
    choices.push(2);
    displayInput.style.color = "black";
});
buttons.button3.addEventListener("click", () => {
    displayInput.textContent += "3";
    choices.push(3);
    displayInput.style.color = "black";
});
buttons.button4.addEventListener("click", () => {
    displayInput.textContent += "4";
    choices.push(4);
    displayInput.style.color = "black";
});
buttons.button5.addEventListener("click", () => {
    displayInput.textContent += "5";
    choices.push(5);
    displayInput.style.color = "black";
});
buttons.button6.addEventListener("click", () => {
    displayInput.textContent += "6";
    choices.push(6);
    displayInput.style.color = "black";
});
buttons.button7.addEventListener("click", () => {
    displayInput.textContent += "7";
    choices.push(7);
    displayInput.style.color = "black";
});
buttons.button8.addEventListener("click", () => {
    displayInput.textContent += "8";
    choices.push(8);
    displayInput.style.color = "black";
});
buttons.button9.addEventListener("click", () => {
    displayInput.textContent += "9";
    choices.push(9);
    displayInput.style.color = "black";
});
buttons.buttonDel.addEventListener("click", () => {
    displayInput.textContent = "";
    choices.length = 0;
    operators.length = 0;
});
buttons.buttonDot.addEventListener("click", () => {
    displayInput.textContent = "I do nothing!";
    displayInput.style.color = "black";
});
buttons.buttonAdd.addEventListener("click", () => {
    displayInput.textContent += " + ";
    operators.push(" + ")
    displayInput.style.color = "black";
});
buttons.buttonSubtract.addEventListener("click", () => {
    displayInput.textContent += " - ";
    operators.push(" - ");
    displayInput.style.color = "black";
});
buttons.buttonMultiply.addEventListener("click", () => {
    displayInput.textContent += " x ";
    operators.push(" * ")
    displayInput.style.color = "black";
});
buttons.buttonDivide.addEventListener("click", () => {
    displayInput.textContent += " / ";
    operators.push(" / ")
    displayInput.style.color = "black";
});

// invokes calculate() with arguments
buttons.buttonEquals.addEventListener("click", () => {
    displayInput.textContent = calculate(choices[0], operators[0], choices[1]);
    displayInput.style.color = "green";
});

// dark mode button
let pageBody = document.querySelector("body");
let darkMode = document.getElementById("darkMode");
let footerText = document.querySelector("h3")
darkMode.addEventListener("click", () => {
    pageBody.style.background = "black";
    footerText.style.color = "snow";
});

解决方案

核心思路是维护当前输入的数字字符串、已存储的第一个操作数、选中的运算符三个状态,替代原有的单数字数组存储方式:

1. 替换状态变量

// 替换原有的choices和operators数组
let currentNum = ""; // 存储当前正在输入的数字(字符串形式,方便拼接多位数)
let firstNum = null; // 存储第一个操作数(转为数字类型)
let operator = null; // 存储选中的运算符

2. 重构数字按键逻辑

统一处理所有数字按键,将点击的数字追加到currentNum字符串中:

// 统一数字按键处理函数,避免重复代码
function handleNumberClick(num) {
  currentNum += num;
  displayInput.textContent = currentNum;
  displayInput.style.color = "black";
}

// 绑定所有数字按键事件
buttons.button0.addEventListener("click", () => handleNumberClick("0"));
buttons.button1.addEventListener("click", () => handleNumberClick("1"));
buttons.button2.addEventListener("click", () => handleNumberClick("2"));
buttons.button3.addEventListener("click", () => handleNumberClick("3"));
buttons.button4.addEventListener("click", () => handleNumberClick("4"));
buttons.button5.addEventListener("click", () => handleNumberClick("5"));
buttons.button6.addEventListener("click", () => handleNumberClick("6"));
buttons.button7.addEventListener("click", () => handleNumberClick("7"));
buttons.button8.addEventListener("click", () => handleNumberClick("8"));
buttons.button9.addEventListener("click", () => handleNumberClick("9"));

3. 重构运算符按键逻辑

点击运算符时,将当前输入的数字转为第一个操作数,存储运算符并清空当前输入:

// 统一运算符处理函数
function handleOperatorClick(op) {
  if (currentNum === "") return; // 避免未输入数字时点击运算符
  firstNum = parseFloat(currentNum);
  operator = op;
  displayInput.textContent += ` ${op} `;
  currentNum = ""; // 重置当前输入,准备输入第二个操作数
  displayInput.style.color = "black";
}

// 绑定所有运算符按键事件
buttons.buttonAdd.addEventListener("click", () => handleOperatorClick("+"));
buttons.buttonSubtract.addEventListener("click", () => handleOperatorClick("-"));
buttons.buttonMultiply.addEventListener("click", () => handleOperatorClick("*"));
buttons.buttonDivide.addEventListener("click", () => handleOperatorClick("/"));

4. 重构等号按键逻辑

点击等号时,获取第二个操作数,调用计算函数,同时支持连续运算:

buttons.buttonEquals.addEventListener("click", () => {
  // 校验必要条件:第一个数、运算符、第二个数都必须存在
  if (firstNum === null || operator === null || currentNum === "") return;
  
  const secondNum = parseFloat(currentNum);
  const result = calculate(firstNum, operator, secondNum);
  
  displayInput.textContent = result;
  displayInput.style.color = "green";
  
  // 支持连续运算:将结果设为第一个操作数,清空当前输入和运算符
  firstNum = result;
  currentNum = "";
  operator = null;
});

5. 修正计算函数的运算符匹配

调整运算符判断条件,匹配新存储的运算符格式:

function calculate(a, operator, b){
  if (operator === "+") return a + b;
  else if (operator === "-") return a - b;
  else if (operator === "*") return a * b;
  else if (operator === "/") return a / b;
}

6. 重置按钮逻辑调整

清空所有状态变量:

buttons.buttonDel.addEventListener("click", () => {
  displayInput.textContent = "";
  currentNum = "";
  firstNum = null;
  operator = null;
});

内容的提问来源于stack exchange,提问作者rhysez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 03:57:08