如果没有计算器构造函数,我怎么能重写这段代码呢?

How could I re-write this code without the Calculator constructor?

我正在为 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 = ''
    }
  }
}

首先评论:构造函数的参数是无用的,因为构造函数通过调用 clear.

立即分配新值

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

在后一种情况下(全局),将每个当前 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