Post #9 Calculator Math Func OOP

Coding Corner functions oop procedural

Simple Calculator – Functional and Object-Oriented Approach

In this never-ending calculator example I implemented both functional and object-oriented solutions. The main-function.js file in the project contains console logs as well as Person examples in both the constructor function and modern class syntax.

GitHub Calculator Repo

let input1 = document.getElementById('input1');
let input2 = document.getElementById('input2');
let input3 = document.getElementById('input3');

let input4 = document.getElementById('input4');
let input5 = document.getElementById('input5');
let input6 = document.getElementById('input6');

console.log(input4);
console.log(input5);
console.log(input6);

// Function

input1.addEventListener('mouseout', sum);
input2.addEventListener('mouseout', sum);

function sum() {
  let result = parseInt(input1.value || 0) + parseInt(input2.value || 0);
  input3.value = result;
  console.log(input3.value);
}

input4.addEventListener('mouseout', sub);
input5.addEventListener('mouseout', sub);

function sub() {
  let result = parseInt(input4.value || 0) -
    parseInt(input5.value || 0);
  input6.value = result;
  console.log(input6.value);
}

// OOP version 

class Calculator {
  calculate(operand1, operator, operand2) {
    switch (operator) {
      case '+':
        return operand1 + operand2;
      case '-':
        return operand1 - operand2;
      default:
        return NaN; // Invalid operator
    }
  }
}

const calculator = new Calculator();

document.getElementById('calculate').addEventListener('click', function () {
  const operand1 = parseFloat(document.getElementById('operand1').value) || 0;
  const operator = document.getElementById('operator').value.trim();
  const operand2 = parseFloat(document.getElementById('operand2').value) || 0;

  const result = calculator.calculate(operand1, operator, operand2);
  if (!isNaN(result)) {
    document.getElementById('result').value = result;
  } else {
    alert('Invalid operator! Please enter "+" or "-".');
  }
});

class Calculator2 {
  constructor() {
    this.result = 0;
  }

  add(a, b) {
    this.result = a + b;
  }
}

// Extra OOP example Person

function Person(name, age) {
  this.name = name;
  this.age = age;
}

let person1 = new Person("John", 30);

console.log(person1);

class Person2 {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

let person2 = new Person("Alice", 25);

console.log(person2);

let sumOfAges = person1.age + person2.age;

console.log('Sum of ages: ', sumOfAges);

The calculator still needs more features and UI polish. Below is a walk-through of the code and the two styles.

Code Walkthrough – Functional vs. OOP

The project demonstrates two implementation styles: a functional (procedural) approach and an object-oriented (OOP) approach. Let’s review them step by step.

Functional Approach

The functional part handles simple addition and subtraction by combining DOM manipulation with event listeners.

1. Grabbing HTML elements

let input1 = document.getElementById('input1');
let input2 = document.getElementById('input2');
let input3 = document.getElementById('input3');
let input4 = document.getElementById('input4');
let input5 = document.getElementById('input5');
let input6 = document.getElementById('input6');

The code stores references to the input fields rendered on the page.

2. Logging input references

console.log(input4);
console.log(input5);
console.log(input6);

These lines log the input references to the console; the actual values are not recorded yet.

3. Handling mouseout events

input1.addEventListener('mouseout', sum);
input2.addEventListener('mouseout', sum);
  • When the user leaves input1 or input2, the sum() function fires.
input4.addEventListener('mouseout', sub);
input5.addEventListener('mouseout', sub);
  • When the user leaves input4 or input5, the sub() function runs.

4. sum() – adding numbers

function sum() {
  let result = parseInt(input1.value || 0) + parseInt(input2.value || 0);
  input3.value = result;
  console.log(input3.value);
}
  • Reads values from input1 and input2, converting them to integers.
  • Defaults empty fields to 0.
  • Calculates the sum, writes the result into input3, and logs it.

5. sub() – subtracting numbers

function sub() {
  let result = parseInt(input4.value || 0) - parseInt(input5.value || 0);
  input6.value = result;
  console.log(input6.value);
}
  • Reads values from input4 and input5, converting them to integers.
  • Performs subtraction.
  • Stores the result in input6 and logs it.

Object-Oriented Approach (OOP)

The OOP part relies on classes to organize logic and make reuse easier.

1. Calculator class

class Calculator {
  calculate(operand1, operator, operand2) {
    switch (operator) {
      case '+':
        return operand1 + operand2;
      case '-':
        return operand1 - operand2;
      default:
        return NaN; // Invalid operator
    }
  }
}
  • The class exposes a calculate() method that accepts an operator.
  • Depending on whether the operator is + or -, it returns the proper result.

2. Creating an instance and handling clicks

const calculator = new Calculator();

document.getElementById('calculate').addEventListener('click', function () {
  const operand1 = parseFloat(document.getElementById('operand1').value) || 0;
  const operator = document.getElementById('operator').value.trim();
  const operand2 = parseFloat(document.getElementById('operand2').value) || 0;

  const result = calculator.calculate(operand1, operator, operand2);
  if (!isNaN(result)) {
    document.getElementById('result').value = result;
  } else {
    alert('Invalid operator! Please enter "+" or "-".');
  }
});
  • Creates an object named calculator.
  • Registers a click listener on the calculate button.
  • On click, reads the operands and operator.
  • Calls calculator.calculate() and prints the outcome or shows an error.

3. Calculator2 class

class Calculator2 {
  constructor() {
    this.result = 0;
  }

  add(a, b) {
    this.result = a + b;
  }
}
  • Holds a result property and an add() method, although the instance is not used elsewhere. It simply illustrates how OOP can encapsulate state.

4. Building Person objects

Constructor function (classic approach)

function Person(name, age) {
  this.name = name;
  this.age = age;
}

let person1 = new Person("John", 30);
console.log(person1);
  • Creates person1 with name and age properties.

Person2 class (modern approach)

class Person2 {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

let person2 = new Person("Alice", 25);
console.log(person2);
  • Instantiates person2 using ES6 class syntax.

5. Calculating the sum of ages

let sumOfAges = person1.age + person2.age;
console.log('Sum of ages: ', sumOfAges);
  • Adds the ages of person1 and person2 and logs the total.

Summary – Functional vs. OOP Differences

Functional programming focuses on independent functions that perform specific tasks. Each function is stateless—the work happens entirely inside the function body. The upside is simplicity and clarity, but the code can become harder to expand as the application grows.

Object-oriented programming groups logic into classes and objects. Objects can keep state (for example, the calculator result in this.result), which makes the code more modular. You can create multiple instances, increasing reuse. Even though the codebase is larger, it becomes easier to maintain and scale.

When should you choose each approach?

  • If the code is simple and does not need much orchestration → choose the functional approach.
  • If the code needs to be extensible and reusable → reach for the OOP approach.