Search code examples
javascriptprototype

Trying to learn functional mixins


I have a calculator function:

var Calculator = function(a, b) { 
  this.add = function(a, b) { return a + b; }; 
  this.multiply = function(a, b) { return b * a; }; 
  this.subtract = function(a, b) { return a - b; }; 
  this.divide = function(a, b) { 
    if (a/b === Infinity) {
      return Infinity - Infinity; 
    } else return a/b; 
  }; 
};

I want to create a functional mixin for 'sum' (Calculator.sum) so if I pass "1,2,3,4" into it, it will return 10 but not be a property of Calculator

Can someone explain how this can be done?


Solution

  • Supposing you are talking about the functional mixin pattern described here:

    const withSum = (object) => {
      return Object.assign({}, object, {
        sum(...args) {
          return args.reduce((sum, number) => sum + number, 0);
        }
      });
    };
    
    var Calculator = function(a, b) { 
      this.add = function(a, b) { return a + b; }; 
      this.multiply = function(a, b) { return b * a; }; 
      this.subtract = function(a, b) { return a - b; }; 
      this.divide = function(a, b) { 
        if (a/b === Infinity) {
          return Infinity - Infinity; 
        } else return a/b; 
      }; 
    };
    
    var calculator = withSum(new Calculator(1, 2));
    
    console.log('calculator.add(1, 2):', calculator.add(1, 2));
    console.log('calculator.multiply(1, 2):', calculator.multiply(1, 2));
    console.log('calculator.subtract(2, 1):', calculator.subtract(2, 1));
    console.log('calculator.divide(1, 2):', calculator.divide(1, 2));
    console.log('calculator.sum(1, 2, 3, 4): ', calculator.sum(1, 2, 3, 4));

    Note that if your Calculator.divide is supposed to return NaN if a/b === Infinity you can simply write return NaN; instead of Infinity - Infinity (NaN is a global constant).

    Also, you can delete the formal parameter list declared in the Calculator constructor: function Calculator() {...} is sufficient because you never use a, b.