Building a Chain Calculator in JavaScript: Method Chaining for Clean Arithmetic

Mohammad TalimMohammad Talim
4 min read

In this post, we'll explore how to design a Chain Calculator—a calculator class that lets you perform a series of arithmetic operations using a fluent, chainable interface. This is a popular interview question and a great exercise to deepen your understanding of JavaScript classes and method chaining.

Why Method Chaining?

Method chaining is a programming pattern that allows multiple method calls in a single statement, improving code readability and succinctness. It's used widely in libraries like jQuery and Lodash, and it's a great tool for creating intuitive APIs. By building a chainable calculator, you'll learn how to design methods that return this, enabling seamless chaining of operations.

The Problem

Design a Chain Calculator in JavaScript that supports method chaining for basic arithmetic operations:

  • Addition

  • Subtraction

  • Multiplication

  • Division

  • Exponentiation (power)

The calculator should allow users to perform a sequence of operations in one line, like this:

const calc = new Calculator(10);
const result = calc.add(5).subtract(3).multiply(2).divide(3).getResult(); // 8

Requirements

  • Initial value: The calculator starts with a number passed to its constructor.

  • Chainable methods: Support these methods:

    • add(number)

    • subtract(number)

    • multiply(number)

    • divide(number)

    • power(number)

  • All arguments are valid numbers.

  • Division by zero should throw an error.

  • The final result is retrieved with getResult().

Approach: Using Classes and Chaining

To achieve method chaining, each arithmetic method will:

  • Modify the calculator's internal state.

  • Return this so calls can be chained.

We'll use a class to encapsulate state and behavior. For error handling, division by zero will throw an exception.

Why Not a Functional Approach?

You might wonder: why not just use functions and closures? While possible, the class-based approach is more idiomatic for method chaining in JavaScript and is more readable, especially in interview settings.


Implementation: Step by Step

Let's build the Calculator class step by step.

1. The Skeleton

class Calculator {
  constructor(value) {
    this.result = value;
  }
}

2. Arithmetic Methods

Each method updates the result and returns this:

add(value) {
  this.result += value;
  return this;
}

subtract(value) {
  this.result -= value;
  return this;
}

multiply(value) {
  this.result *= value;
  return this;
}

3. Division with Error Handling

divide(value) {
  if (value === 0) {
    throw new Error("Division by zero is not allowed");
  }
  this.result /= value;
  return this;
}

4. Exponentiation

power(value) {
  this.result **= value;
  return this;
}

5. Retrieving the Result

getResult() {
  return this.result;
}

6. The Complete Class

class Calculator {
  constructor(value) {
    this.result = value;
  }

  add(value) {
    this.result += value;
    return this;
  }

  subtract(value) {
    this.result -= value;
    return this;
  }

  multiply(value) {
    this.result *= value;
    return this;
  }

  divide(value) {
    if (value === 0) {
      throw new Error("Division by zero is not allowed");
    }
    this.result /= value;
    return this;
  }

  power(value) {
    this.result **= value;
    return this;
  }

  getResult() {
    return this.result;
  }
}

Example Usage

Let's see this calculator in action:

const calc = new Calculator(10);
console.log(calc.add(5).subtract(3).multiply(2).divide(3).getResult()); // Output: 8

More Examples

ExpressionOutputExplanation
new Calculator(10).add(5).subtract(3).getResult()1210 + 5 - 3 = 12
new Calculator(2).multiply(5).power(2).getResult()100(2 × 5)² = 10² = 100
new Calculator(20).divide(4).add(2).multiply(3).getResult()2120 ÷ 4 = 5, 5 + 2 = 7, 7 × 3 = 21
new Calculator(5).divide(0).getResult()ErrorThrows error for division by zero
new Calculator(7).getResult()7No operations; returns initial value

Time and Space Complexity

  • Time Complexity: O(1) per operation (each method does a simple calculation).

  • Space Complexity: O(1) (stores only a single number).

Key Takeaways

  • Always return this from methods to enable chaining.

  • Handle errors (like division by zero) gracefully.

  • This pattern—called the fluent interface—makes APIs easy and intuitive to use.

Further Reading

0
Subscribe to my newsletter

Read articles from Mohammad Talim directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Mohammad Talim
Mohammad Talim

Final year student and front-end developer passionate about building beautiful and user-friendly experiences. Writing about web development and design.