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 
thisso 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
| Expression | Output | Explanation | 
|---|---|---|
new Calculator(10).add(5).subtract(3).getResult() | 
12 | 10 + 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() | 
21 | 20 ÷ 4 = 5, 5 + 2 = 7, 7 × 3 = 21 | 
new Calculator(5).divide(0).getResult() | 
Error | Throws error for division by zero | 
new Calculator(7).getResult() | 
7 | No 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 
thisfrom methods to enable chaining. - Handle errors (like division by zero) gracefully.
 - This pattern—called the fluent interface—makes APIs easy and intuitive to use.
 
              
    
Top comments (0)