I've been trying to learn and implement object oriented programming in JavaScript.
Could you please provide some advice and feedback (primarily on the application of OOP, overall code efficiency and proper use of patterns)?
Code explanation:
The code consists of a calculator constructor which has basic functions: add
, subtract
, divide
and multiply
, clear
, equal
.
The input
method captures the content of clicks assigns them to input variable and runs some basic filters.
If the input is a number, it's appended to the variable number as a string.
If any of the operators are clicked, the contents of the variable number
and the operator is added to inputArray
. This creates a list of numbers and operators in a sequence.
If the '=' sign is clicked, the equal
method is run, which loops through inputArray
and assigns division and multiplication followed by add and subtract.
Once the equal
method completes, inputArray
is left with one number, result
, which is displayed on the screen.
The printEquation
method simply prints out the contents of inputArray
on the screen.
Here's the equation that has been typed so far:
function Calculator() {
"use strict";
var inputArray = [],
operations = ["x", "/", "+", "-"],
number = "",
i,
that = this,
equation = document.getElementById("equation"),
display = document.getElementById("display");
display.textContent = "0";
this.add = function(a, b) {
var c = inputArray[a] + inputArray[b];
inputArray[a] = c;
inputArray.splice(a + 1, 2);
i -= 2;
};
this.substract = function(a, b) {
var c = inputArray[a] - inputArray[b];
inputArray[a] = c;
inputArray.splice(a + 1, 2);
i -= 2;
};
this.divide = function(a, b) {
var c = inputArray[a] / inputArray[b];
if (isNaN(c)) {
c = 0;
}
inputArray[a] = c;
inputArray.splice(a + 1, 2);
i -= 2;
};
this.multiply = function(a, b) {
var c = inputArray[a] * inputArray[b];
inputArray[a] = c;
inputArray.splice(a + 1, 2);
i -= 2;
};
this.equal = function() {
for (i = 0; i < inputArray.length; i += 1) {
if (inputArray[i] === "/") {
that.divide(i - 1, i + 1);
}
if (inputArray[i] === "x") {
that.multiply(i - 1, i + 1);
}
}
for (i = 0; i < inputArray.length; i += 1) {
if (inputArray[i] === "+") {
that.add(i - 1, i + 1);
}
if (inputArray[i] === "-") {
that.substract(i - 1, i + 1);
}
}
display.textContent = inputArray[0];
};
this.clear = function() {
inputArray = [];
number = "";
display.textContent = "0";
equation.textContent = "";
};
this.printEquation = function() {
equation.textContent = "";
for (i = 0; i < inputArray.length; i += 1) {
equation.textContent += inputArray[i];
}
};
this.input = function(e) {
var input = e.target.textContent;
var testInput = operations.indexOf(input) === -1 ? false : true;
//Add a zero if operator is clicked without any input
if (testInput && number === "") {
number = "0";
}
//Run clear if equal is clicked without any input
if (input === "=" && inputArray.length === 0) {
this.clear;
} else if (testInput) {
inputArray.push(parseInt(number, 10));
inputArray.push(input);
number = "";
display.textContent = "0";
that.printEquation();
} else if (input === "C") {
that.clear();
} else if (input === "=") {
if (number !== "") {
inputArray.push(parseInt(number, 10));
number = "";
that.printEquation();
that.equal();
} else {
inputArray.pop();
number = "";
that.equal();
}
} else {
number += input;
display.textContent = number;
}
};
}
//Initialise calculator
var calci = new Calculator();
var nodes = document.getElementById("calBtn").childNodes;
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].nodeName.toLowerCase() === "span") {
nodes[i].addEventListener("click", calci.input)
}
}
* {
-webkit-box-sizing: border-box;
box-sizing: border-box;
font: 500 1.1em sans-serif;
background-color: mintcream;
color: darkslategray;
}
h1,
h2 {
font: 500 sans-serif;
}
h1 {
font-size: 1.5em;
}
.wrapper {
margin: 0 auto;
text-align: center;
}
#calculator {
width: 330px;
height: auto;
background-color: blanchedalmond;
border: 1px solid gray;
padding: 2px;
text-align: center;
margin: 0 auto;
}
#calBtn {
background-color: inherit;
}
#calBtn span {
display: inline-block;
background-color: lightgray;
width: 71px;
height: 50px;
line-height: 50px;
text-align: center;
vertical-align: middle;
margin: 5px;
cursor: pointer;
outline: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
#calBtn span:hover {
-webkit-box-shadow: none;
box-shadow: none;
border: 0.5px solid gray;
}
.screen {
width: 95%;
height: auto;
border: 0.5px solid gray;
margin: 15px auto 10px auto;
}
#calculator,
#calBtn span,
.screen {
-webkit-box-shadow: 1px 1px 2px darkslateblue;
box-shadow: 1px 1px 2px darkslateblue;
border-radius: 5px;
}
#equation,
#display {
display: block;
width: 93%;
height: 40px;
line-height: 40px;
margin: 0 auto;
text-align: right;
padding: 1px 0;
}
@media only screen and (max-width: 768px) {
#calBtn span {
height: 71px;
line-height: 71px;
}
}
<body>
<div class="wrapper">
<div id="calculator">
<div class="screen">
<span id="equation"></span>
<span id="display"></span>
</div>
<div id="calBtn">
<span>7</span><!--
--><span>8</span><!--
--><span>9</span><!--
--><span>/</span><!--
--><br><!--
--><span>4</span><!--
--><span>5</span><!--
--><span>6</span><!--
--><span>x</span><!--
--><br><!--
--><span>1</span><!--
--><span>2</span><!--
--><span>3</span><!--
--><span>-</span><!--
--><br><!--
--><span>0</span><!--
--><span>C</span><!--
--><span>=</span><!--
--><span>+</span>
</div>
</div>
</div>
</body>