题目
答案一
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const add = num => num + 10; const mult = num => num*2; const other = num => num *3;
const compose = function () { const _o = Array.from(arguments) || []; return function inner(...rest) { if (!_o.length) { return } if (_o.length > 1) { return inner.call(null, _o.splice(0, 1)[0].apply(null, rest)) }
return _o[0].apply(null, rest); } }
|
方案二
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const add = num => num + 10; const mult = num => num*2; const other = num => num *3;
function compose(...funcs) { if (funcs.length === 0) { return arg => arg }
if (funcs.length === 1) { return funcs[0] }
return funcs.reduceRight((a, b) => (...args) => a(b(...args))) }
|
上面是比较好的两种方法,其中第一种是利用了递归的思路,第二种利用了reduce
函数,实现了函数组合,至于函数组合的执行顺序,借助reduce
&reduceRight
来控制。
End
结尾处,可以再次引什出函数柯里化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
const carry = (f, o) => { o = o || []; const _len = f.length;
return function () { const _o = [...o.slice(), ...Array.from(arguments)];
if(_o.length < _len) { return carry.call(this, f, _o); }
return f.apply(this, _o); } };
const sum = (a,b,c) => a+b+c; const newSum = carry(sum);
console.log(newSum(1)(2)(3));
|
核心思维:借助闭包的活动对象,保留柯里参数,当柯里参数与被柯里函数的参数长度一致的时候执行。