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