Igor Shvets
Igor Shvets

Reputation: 547

How to multiply numbers in a closure

How to implement a locking function for multiplying an arbitrary number of numbers.

Example of a call:

multiply(1)(2)(3)(4)(5) // 120

To accomplish this task, it is necessary to redefine the toString method for the internal function, which should return the accumulated result, but I had result NaN.

function Multiply(arguments) {
  for (var i = 0; i < arguments.length; i++) {
    var number = arguments.length[i];
  }
  return function(res) {
    return number * res.valueOf();
  };
}
console.log(Multiply(5)(5)(6)(8));

Upvotes: 4

Views: 3129

Answers (3)

Pranav C Balan
Pranav C Balan

Reputation: 115242

You can implement it by overwriting Function#toString method which would call internally in major caser(for eg: while using with alert() function, string concatenation, etc...).

function Multiply(arg) {
  // calcumate the multiplication result
  var res = (this.value || 1) * arg,
    // bind this argument as an object which contains previous result
    returnFn = Multiply.bind({
      value: res
    })

  // overwrite toString method to return the current result
  returnFn.toString = function() {
    return res;
  }

  // return the function 
  return returnFn;
}


console.log(Multiply(5)(5)(6)(8));

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386680

First of all do not use arguments as parameter in a function, because this variable is available in functions as array like object for the arguments of the function (arguments object).

Then you need to have an inner function m which uses the arguments and calculates the product and returns the function itself.

The inner function gets a toString method for getting the final result.

At last you need to call the inner function with all arguments of the outer function.

A small hint, take only a lower case letter for not instanciable function.

function multiply(...args) {
    function m(f, ...a) {
        p *= f;
        if (a.length) {
            m(...a);
        }
        return m;
    }

    var p = 1;            // neutral value for multiplication
    m.toString = _ => p;
    return m(...args);
}

console.log(multiply(5)(5)(6)(8));
console.log(multiply(2, 3, 4)(5)(6, 7));

Upvotes: 5

ibrahim mahrir
ibrahim mahrir

Reputation: 31712

  1. The function returned by Multiply should return itself after each call.
  2. valueOf should be assigned to that function not to its argument which will be a number.
  3. Multiply should call the inner function with its argument (the initial number).
  4. No need to use the arguments object as there will always be one argument.

function Multiply(initialNum) {
    var product = 1;

    function fn(num) {
        product *= num;
        return fn;
    };

    fn.valueOf = function() { return product; };

    return fn(initialNum);
}

console.log(0 + Multiply(5)(5)(6)(8));

Note: The 0 + in console.log is to assure that valueOf will be called as the SO snippett console doesn't seem to work properly.

Upvotes: 4

Related Questions