1

我正在为为期 12 周的训练营制作计算器,MVP 声明我们不使用构造函数。

下面是构造函数中的所有函数。我需要所有函数继续工作,我只需要它们不在构造函数中以满足我的 MVP 的要求。

我从概念上了解如何制作计算器,并选择梳理和重写 vanilla JS,并在整个过程中添加注释以巩固我的理解。

class Calculator {
  constructor(previousOperandTextElement, currentOperandTextElement) {
    this.previousOperandTextElement = previousOperandTextElement
    this.currentOperandTextElement = currentOperandTextElement
    this.clear()
  }

  clear() {
    this.currentOperand = ''
    this.previousOperand = ''
    this.operation = undefined
  }

  delete() {
    this.currentOperand = this.currentOperand.toString().slice(0, -1)
  }

  appendNumber(number) {
    if (number === '.' && this.currentOperand.includes('.')) return
    this.currentOperand = this.currentOperand.toString() + number.toString()
  }

  chooseOperation(operation) {
    if (this.currentOperand === '') return
    if (this.previousOperand !== '') {
      this.compute()
    }
    this.operation = operation
    this.previousOperand = this.currentOperand
    this.currentOperand = ''
  }

  compute() {
    let computation
    const prev = parseFloat(this.previousOperand)
    const current = parseFloat(this.currentOperand)
    if (isNaN(prev) || isNaN(current)) return
    switch (this.operation) {
      case '+':
        computation = prev + current
        break
      case '-':
        computation = prev - current
        break
      case '*':
        computation = prev * current
        break
      case '÷':
        computation = prev / current
        break
      default:
        return
    }
    this.currentOperand = computation
    this.operation = undefined
    this.previousOperand = ''
  }

  getDisplayNumber(number) {
    const stringNumber = number.toString()
    const integerDigits = parseFloat(stringNumber.split('.')[0])
    const decimalDigits = stringNumber.split('.')[1]
    let integerDisplay
    if (isNaN(integerDigits)) {
      integerDisplay = ''
    } else {
      integerDisplay = integerDigits.toLocaleString('en', { maximumFractionDigits: 0 })
    }
    if (decimalDigits != null) {
      return `${integerDisplay}.${decimalDigits}`
    } else {
      return integerDisplay
    }
  }

  updateDisplay() {
    this.currentOperandTextElement.innerText =
      this.getDisplayNumber(this.currentOperand)
    if (this.operation != null) {
      this.previousOperandTextElement.innerText =
        `${this.getDisplayNumber(this.previousOperand)} ${this.operation}`
    } else {
      this.previousOperandTextElement.innerText = ''
    }
  }
}
4

1 回答 1

0

首先是评论:构造函数的参数是无用的,因为构造函数通过调用立即分配新值clear

如果没有原型(类实例)函数,您可以给每个函数一个表示计算器状态的参数。或者,如果您将使用此类仅创建一个实例,则可以将该状态设为全局,这可能是初学者课程中建议的方法。

在后一种情况下(全局变量),将每个当前this属性定义为全局变量,如下所示:

var previousOperandTextElement = "", 
    currentOperandTextElement = "",
    operation;

接着:

  • this.从代码中删除所有出现的
  • 在每个方法之前插入function关键字
  • 从全局声明的constructor正下方移动任何代码var
  • 删除class包装器和constructor函数

像这样:

var previousOperandTextElement = "", 
    currentOperandTextElement = "",
    operation;

clear();

function clear() {
    currentOperand = ''
    previousOperand = ''
    operation = undefined
}

function delete() {
    currentOperand = currentOperand.toString().slice(0, -1)
}

function appendNumber(number) {
    if (number === '.' && currentOperand.includes('.')) return
    currentOperand = currentOperand.toString() + number.toString()
}

// ...etc ...etc
于 2021-10-01T06:27:56.040 回答