Write a function that satisfies the following.
add(1)(2).value() = 3; add(1, 2)(3).value() = 6; add(1)(2)(3).value() = 6; add(1)(2) + 3 = 6;
This question is part of the currying methodology in JavaScript.
Currying in JavaScript is a concept of functional programming in which we can pass functions as arguments (callbacks) and return functions without any side effects (Changes to program states).
This is a little tricky question and requires us to use and modify the valueOf() method.
When JavaScript wants to turn an object into a primitive value, it uses the function valueOf() method. JavaScript automatically calls the function valueOf() method when it comes across an object where a primitive value is anticipated, so you don’t even need to do it yourself.
Example
function MyNumberType(n) { this.number = n; } MyNumberType.prototype.valueOf = function () { return this.number + 1; }; const myObj = new MyNumberType(4); myObj + 3; // 8
Thus we can form closure and track the arguments in an Array and return a new function every time that will accept new arguments.
We will also override the valueOf()
method and return the sum of all the arguments for each primitive action, also add a new method value()
that will reference the valueOf()
thus when invoked will return the sum of arguments.
function add(...x){ // store the current arguments let sum = x; function resultFn(...y){ // merge the new arguments sum = [...sum, ...y]; return resultFn; } // override the valueOf to return sum resultFn.valueOf = function(){ return sum.reduce((a, b) => a + b, 0); }; // extend the valueOf resultFn.value = resultFn.valueOf; // return the inner function // on any primitive action .valueOf will be invoked // and it will return the value return resultFn; }
Input: console.log(add(1)(2).value() == 3); console.log(add(1, 2)(3).value() == 6); console.log(add(1)(2)(3).value() == 6); console.log(add(1)(2) + 3); Output: true true true 6