I am making a calculator for a 12 week bootcamp and the MVP states we are not to use constructors.
Below is all the functions within the constructor. I need all of the functions to continue to work, I just need them NOT inside a constructor to meet the requirements of my MVP.
I understand conceptually how to make a calculator, and have opted to comb through and rewrite vanilla JS with notes throughout to solidify my understanding.
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 = ''
}
}
}
First a comment: the parameters to the constructor are useless, as the constructor assigns new values immediately by its call to clear
.
Without prototype (class instance) functions, you could give every function a parameter that represents the state of the calculator. Or, if you would have used this class to create one instance only, you could make that state global, which is what may be the suggested approach in a beginner's course.
In the latter case (globals), define each current this
property as global variable, like this:
var previousOperandTextElement = "",
currentOperandTextElement = "",
operation;
And then:
this.
from the codefunction
keyword before every methodconstructor
just below the global var
declarationsclass
wrapper and the constructor
functionLike so:
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