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