函数柯里化
- 把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数。
- 优点:提高了代码的合理性,更重的它突出一种思想---降低适用范围,提高适用性。
例子一
function add(a, b, c, d, e, f) {
return a + b + c + d + e + f;
}
let r = add(1, 2, 3, 4, 5, 6);
// 需要被curry的方法必须有固定长度参数
function curring(fn, arr = []) {
let length = fn.length;
return function(...args) {
arr = [...arr, ...args];
if (arr.length < length)
return curring(fn, arr);
else
return fn(...arr);
}
}
let r1 = curring(add)(1, 2)(3, 4)(5, 6);
console.log(r1);
例子二
function checkType(type, value) {
return Object.prototype.toString.call(value) === `[object ${type}]`
}
let util = {};
let types = ['String', 'Number', 'Boolean', 'Null', 'Undefind'];
types.forEach(type => {
util['is' + type] = curring(checkType)(type);
});
let r2 = util['isString']('123');
console.log(r2);
反柯里化-uncurrying
- 作用就是扩大函数应用范围
let r1 = Array.prototype.join.apply([1, 2, 3], ['-']);
console.log(r1);
- 弄个反柯里化函数让其动态生成新函数
let join = uncurrying(Array.prototype.join);
let r = join([1, 2, 3], '-');
console.log(r);
- 简单写法
// 这种写法有个bug,保证值是原型的上的call方法
// 比如刚好fn上有call方法 fn.call=()=>{};就会出问题
// function uncurrying(fn) {
// return function(context, ...args) {
// return fn.call(context, ...args);
// }
// }
- 升级成原型call方法写法
// function uncurrying(fn) {
// return function(context, ...args) {
// return Function.prototype.call.call(fn, context, ...args);
// }
// }
- 升级成原型apply方法写法
// function uncurrying(fn) {
// return function(context, ...args) {
// return Function.prototype.apply.call(fn, context, args);
// }
// }
- 升级成es6的 Reflect.apply
function uncurrying(fn) {
return function(context, ...args) {
return Reflect.apply(fn, context, args);
}
}