If you want to use only one argument-name, perhaps you meant to destructure it: function(...add)
const not_hof = {};
// Cheating by using destructuring (...add)
// and not a HOF since accepts only Numbers as arguments
not_hof.add = function(...add) {
const makeAdd = add.reduce((prev, curr) => {
return prev + curr;
}, 0);
return makeAdd; // and still not a HOF since it returns a Number
};
console.log(not_hof.add(2, 3)); // 5
console.log(not_hof.add(9, 1, 10)); // 20
console.log(not_hof.add(1, 1, 1, 1, 1, 1)); // 6
PS: The above function can be also expressed like:
not_hof.add = (...add) => add.reduce((prev, curr) => prev + curr, 0);
Not a HOF (higher order function)
Although many would say the above is a higher order function - since it returns Array.prototype.reduce
, it's actually not:
Wikipedia - Higher order function
In mathematics and computer science, a higher-order function is a function that does at least one of the following:
- takes one or more functions as arguments (i.e. procedural parameters),
- returns a function as its result.
But add
is not a procedural function argument; i.e:
procedure P(f):
return f(2,3) * f(9,1)
and it does not return a function; rather a Number returned by Array.prototype.reduce
.
1. HOF - One or more functions as arguments
To at least pass a function as argument:
const helper = { // Helper functions
add(a, b) { return Number(a) + Number(b); },
};
const hof = {};
hof.add = function(fn, add1, add2) { // HOF since it takes a function as argument
return fn(add1, add2); // (Returns a Number)
};
// ...But it takes three arguments
console.log(hof.add(helper.add, 56, 5)); // 61
2. HOF - Return a function
To at least return a function:
const hof = {};
hof.add = function(add) { // (Takes a Number argument)
function makeAdd(b) {
return add + b;
}
return makeAdd; // HOF since it returns a function
};
// But accepts a single argument at each call
console.log(hof.add(56)(5)); // 61
or like
const hof = {};
hof.add = function(add1, add2) { // NOT LIKE YOUR EXAMPLE, 2 arguments are expected!
function makeAdd() {
return add1 + add2;
}
return makeAdd; // HOF since it returns a function
};
// ...The function had to be executed ()
console.log(hof.add(56, 5)()); // 61
but in such case it fails what your test states:
it('returns total of the two arguments', () => { // nope :( only one argument here...
HOF with closure
Allows to invoke the function multiple times with a Function.prototype.toString()
in order to return at the last call the string
const hof = {};
hof.add = function(add) {
let sum = add; // Store in local scope
const makeAdd = (b) => {
sum += b; // Access to lexical environment variables
return makeAdd; // Returns a function (self)
}
makeAdd.toString = () => sum;
return makeAdd; // HOF since we return a function
}
const result = hof.add(1)(2)(2)(56);
console.log(result) // (f) 61
console.log(typeof result); // function
console.log(result == 61) // true
console.log(result === 61) // false
// A legitimate test might break since the strict equality operator fails.
Let's keep it simple. No closure, no HOF
If the first example using Array destructuring and Array.prototype.reduce() is not needed, than just stick to the simplest form of a function declaration:
const not_hof = {
add: (a, b) => a + b,
sub: (a, b) => a - b,
// etc...
};
console.log( not_hof.add(56, 5) ); // 61