今天來做一個計算機。
如畫面所示,是一個簡易的計算機,有加、減、乘、除、清除 的功能
const numberButtons = document.querySelectorAll("[data-number]");
const operationButtons = document.querySelectorAll("[data-operation]");
const equalsButton = document.querySelector("[data-equals]");
const deleteButton = document.querySelector("[data-delete]");
const allClearButton = document.querySelector("[data-all-clear]");
const previousOperandTextElement = document.querySelector("[data-previous-operand]");
const currentOperandTextElement = document.querySelector("[data-current-operand]");
const calculator = new Calculator(previousOperandTextElement,
currentOperandTextElement);
下面我們做了一個 Calculator 的 class 和 constructor
類別 (Class) 是先定義好物件的整體結構藍圖(blue print),然後再用這個類別定義,用來產生相同結構的多個的物件,類別在定義時不會直接產生出物件,要經過實體化的過程 (new) ,才會產生真正的物件實體。
函式建構式(function constructor)就是普通的 function,只是我們可以透過這個 function 來建立物件。
在 function 前面加上 new,它會把函式中 this 這個關鍵字建立成一個新的物件,如果沒有在該函式的最後指定回傳出其它物件的話,它就會自動回傳這個新的物件給你。
class Calculator {
constructor(previousOperandTextElement, currentOperandTextElement){
this.previousOperandTextElement = previousOperandTextElement;
this.currentOperandTextElement = currentOperandTextElement;
this.readyToReset = false;
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.currentOperand !== "" && 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.readyToReset = true;
this.currentOperand = computation;
this.operation = undefined;
this.previousOperand = "";
}
// 計算結果顯示
updateDisplay() {
this.currentOperandTextElement.innerText = this.currentOperand;
if (this.operation != null) {
this.previousOperandTextElement.innerText =
`${this.previousOperand} ${this.operation}`
} else {
this.previousOperandTextElement.innerText = "";
}
}
}
allClearButton.addEventListener("click", () => {
calculator.clear();
calculator.updateDisplay();
})
numberButtons.forEach(button => {
button.addEventListener("click", () => {
if(calculator.previousOperand === "" &&
calculator.currentOperand !== "" &&
calculator.readyToReset) {
calculator.currentOperand = "";
calculator.readyToReset = false;
}
calculator.appendNumber(button.innerText)
calculator.updateDisplay();
})
})
operationButtons.forEach(button => {
button.addEventListener("click", () => {
calculator.chooseOperation(button.innerText)
calculator.updateDisplay();
})
})
equalsButton.addEventListener("click", button => {
calculator.compute();
calculator.updateDisplay();
})
deleteButton.addEventListener("click", button => {
calculator.delete();
calculator.updateDisplay();
})
建立 class 的方法,讓思考的思路變得清楚,明天再來看看,其他應用的例子。明天見