返回

成为计算器高手:JS原生实现计算器,非eval,附源码

前端

使用 JS 原生打造功能强大的计算器:免除 eval,尽享流畅计算

在日常生活和工作中,计算器作为不可或缺的工具,在各种数学运算中发挥着至关重要的作用。如果您正在寻找一款可在浏览器中使用的计算器,那么 JS 原生无疑是一个绝佳的选择。

JS 原生计算器的强大功能

JS 原生计算器是一款功能丰富的工具,提供了一系列实用功能:

  • 基础运算: 轻松应对加减乘除等基本运算。
  • 括号运算: 通过括号轻松处理复杂表达式。
  • 清空功能: 一键清除所有输入,方便快速更正。
  • 清空末位: 针对性地清除最后一个输入字符,提升操作效率。
  • 历史记录: 完整记录计算历史,方便回顾和检查。
  • 字体切换: 根据个人喜好调整字体大小,优化视觉体验。
  • 主题切换: 提供多样主题,满足不同用户的审美需求。

实现原理:栈的巧妙运用

JS 原生计算器巧妙地运用了栈这种数据结构来实现其强大的功能。栈遵循后进先出的原则,最新输入的元素最先被处理。在计算器中,栈被用来存储操作数(数字)和运算符(符号)。

当用户输入一个数字时,它会被压入操作数栈。当输入一个运算符时,它会被压入运算符栈。当按下“=”键时,计算器从运算符栈中弹出两个运算符,从操作数栈中弹出两个操作数,根据运算符进行计算,并将结果压入操作数栈。

如果表达式中包含括号,计算器会使用递归的方式处理括号内的子表达式。它会首先找到左括号和右括号的位置,提取括号内的子表达式,并再次调用自身计算子表达式的结果。

代码示例:实现计算器核心功能

// 操作数栈
const operandStack = [];

// 运算符栈
const operatorStack = [];

// 计算表达式
function calculateExpression(expression) {
  // 处理括号内的子表达式
  if (expression.includes("(")) {
    const leftIndex = expression.indexOf("(");
    const rightIndex = expression.indexOf(")");
    const subExpression = expression.substring(leftIndex + 1, rightIndex);
    const subResult = calculateExpression(subExpression);
    expression = expression.replace(`(${subExpression})`, subResult);
  }

  // 将表达式拆分为操作数和运算符
  const tokens = expression.split(/([+\-*/])+/);

  // 将操作数压入操作数栈
  for (const token of tokens) {
    if (!isNaN(token)) {
      operandStack.push(parseFloat(token));
    }
  }

  // 将运算符压入运算符栈
  for (const token of tokens) {
    if (isNaN(token)) {
      operatorStack.push(token);
    }
  }

  // 进行计算
  while (operatorStack.length > 0) {
    const operator = operatorStack.pop();
    const operand1 = operandStack.pop();
    const operand2 = operandStack.pop();
    let result;

    switch (operator) {
      case "+":
        result = operand1 + operand2;
        break;
      case "-":
        result = operand1 - operand2;
        break;
      case "*":
        result = operand1 * operand2;
        break;
      case "/":
        result = operand1 / operand2;
        break;
    }

    operandStack.push(result);
  }

  // 返回计算结果
  return operandStack[0];
}

总结:JS 原生的魅力

JS 原生计算器充分体现了 JS 原生的强大功能和灵活性。它通过栈的巧妙运用和递归的合理处理,实现了高效稳定的计算功能。无论您是日常计算还是复杂数学运算,JS 原生计算器都能轻松胜任,为您提供流畅无忧的计算体验。

常见问题解答

  1. 是否需要使用 eval() 函数?
    答:否。JS 原生计算器完全不依赖 eval() 函数,避免了潜在的安全隐患。

  2. 是否支持历史记录功能?
    答:是。计算器会自动记录每个计算过程,方便您随时回顾和检查。

  3. 如何调整计算器外观?
    答:计算器支持字体大小和主题颜色的切换,您可以根据个人喜好进行调整。

  4. 如何处理括号内的复杂表达式?
    答:计算器会使用递归的方式处理括号内的子表达式,确保优先级正确。

  5. 是否可以自定义计算器的功能?
    答:可以通过修改 JS 代码来自定义计算器的功能,满足您的特定需求。