You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

JavaScript计算器:支持将负数作为首个操作数

解决JavaScript计算器支持负数起始操作数的问题

我来帮你搞定这个负数开头的问题,咱们直接针对代码里的关键点修改就行:

问题根源

原代码里的chooseOperation方法有个判断:if (this.current === '') return;,这就导致当你还没输入任何数字时点击减号,直接就被拦截返回了,根本不会处理减号的逻辑。我们需要给减号做特殊放行,允许它作为负数的起始符号。

修改方案

1. 优化chooseOperation方法

修改这个方法,让减号在当前输入为空时可以被添加到current中,同时处理重复点击减号的情况(比如不小心点了两次减号,应该清空当前输入):

chooseOperation(operator) {
  // 处理重复点击减号的情况:当前已经是减号,再点就清空
  if (operator === '-' && this.current === '-') {
    this.current = '';
    this.updateDisplay();
    return;
  }
  // 特殊放行减号:当前为空时,允许作为负数前缀
  if (operator === '-' && this.current === '') {
    this.current = '-';
    this.updateDisplay();
    return;
  }
  // 原有逻辑:非减号且当前为空时返回
  if (this.current === '') return;
  // 已有前序操作数时先计算结果
  if (this.prev !== '') {
    this.calculate();
  }
  this.operator = operator;
  this.prev = this.current;
  this.current = '';
}

2. 可选:把parseInt改为parseFloat(更通用)

calculate方法里用了parseInt,如果你的计算器以后要支持小数,改成parseFloat会更合适,负数的解析也完全没问题:

calculate() {
  let result;
  // 把parseInt改成parseFloat,支持小数和负数
  const previousValue = parseFloat(this.prev);
  const currentValue = parseFloat(this.current);
  if (isNaN(previousValue) || isNaN(currentValue)) return;
  switch (this.operator) {
    case '+':
      result = previousValue + currentValue;
      break;
    case '-':
      result = previousValue - currentValue;
      break;
    default:
      return;
  }
  this.current = result;
  this.operator = undefined;
  this.prev = '';
}

修改后的效果

  • 点击减号(当前为空):会在当前显示区出现-,之后点击数字就能组成负数,比如-123
  • 重复点击减号:第一次显示-,第二次点击会清空当前输入
  • 正常计算流程不受影响:比如先输入正数,再点击减号进行减法运算,逻辑和之前一致

完整修改后的Calculator类代码

class Calculator {
  constructor(prevText, currentText) {
    this.prevText = prevText;
    this.currentText = currentText;
    this.clear();
  }

  clear() {
    this.prev = '';
    this.current = '';
    this.operator = undefined;
  }

  delete() {
    this.current = this.current.toString().slice(0, -1);
    if (this.current === '') {
      this.current = this.prev;
      this.prev = '';
      this.operator = undefined;
    }
  }

  appendNumber(nr) {
    this.current = this.current.toString() + nr.toString();
  }

  chooseOperation(operator) {
    // 处理重复点击减号
    if (operator === '-' && this.current === '-') {
      this.current = '';
      this.updateDisplay();
      return;
    }
    // 允许减号作为负数起始
    if (operator === '-' && this.current === '') {
      this.current = '-';
      this.updateDisplay();
      return;
    }
    if (this.current === '') return;
    if (this.prev !== '') {
      this.calculate();
    }
    this.operator = operator;
    this.prev = this.current;
    this.current = '';
  }

  calculate() {
    let result;
    const previousValue = parseFloat(this.prev);
    const currentValue = parseFloat(this.current);
    if (isNaN(previousValue) || isNaN(currentValue)) return;
    switch (this.operator) {
      case '+':
        result = previousValue + currentValue;
        break;
      case '-':
        result = previousValue - currentValue;
        break;
      default:
        return;
    }
    this.current = result;
    this.operator = undefined;
    this.prev = '';
  }

  getDisplayNr(nr) {
    const floatNr = parseFloat(nr);
    if (isNaN(floatNr)) return '';
    return floatNr.toLocaleString('en');
  }

  updateDisplay() {
    this.currentText.innerText = this.getDisplayNr(this.current);
    if (this.operator != null) {
      this.prevText.innerText = ` ${this.getDisplayNr(this.prev)} ${ this.operator }`;
    } else {
      this.prevText.innerText = '';
    }
  }
}

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

火山引擎 最新活动