js函数式编程之函数柯里化

1. 柯里化实现

柯里化就是将接受多个参数的函数转化成接受单个参数的函数
柯里化后可以生成便捷函数/偏函数

// 以一个实际需求为例:动态生成表格列,添加到固定的表格列中,组成完整的表格列
function composeCols(a, b) {
    a.splice(-1, 0, ...b);
    return a;
}

function curry(f) {
    return function (fixedCols) {  // 包装器1
        return function (dynamicCols) {   // 包装器2
            const fCols = JSON.parse(JSON.stringify(fixedCols));
            return f(fCols, dynamicCols)
        }
    }
}

const curriedFunc = curry(composeCols);
const getCompleteCols = curriedFunc([{name: 'a', value: 1}, {name: 'b', value: 2}]);
console.log(getCompleteCols([{"name":"c","value":3}])); 
//  [{"name":"a","value":1},{"name":"c","value":3},{"name":"b","value":2}]
console.log(getCompleteCols([{"name":"d","value":4}]));
//  [{"name":"a","value":1},{"name":"d","value":4},{"name":"b","value":2}]

// curriedFunc、getCompleteCols就是两个包装器,也可以理解成就是更简短的"偏应用函数(partially applied function)" 或 "偏函数(partial)"
// getCompleteCols为下一步"生成完整的表格列"提供了便捷函数
  1. 高级柯里化
// 以lodash为例
function sum(a, b) {
  return a + b;
}

let curriedSum = _.curry(sum);
// curriedSum包装器允许函数被正常调用或者以偏函数(partial)的方式调用:
alert(curriedSum(1, 2));
alert(curriedSum(1)(2));
  1. 高级柯里化实现
function sum(a, b, c) {
    return a + b + c;
}

function curry(func) {
    return function curried(...args) {
        if (args.length >= func.length) {
            return func(...args);
            // return func.apply(this, args);
        } else {
            return function (...args2) {
                return curried.apply(this, args.concat(args2));
                // return curried(...args.concat(args2));
            }
        }
    }
}

const curriedSum = curry(sum);
console.log(curriedSum(1, 2, 3, 4)); // 6,可以被正常调用
console.log(curriedSum(1)(2,3)); // 6,对第一个参数的柯里化
console.log(curriedSum(1)(2)(3)); // 6, 完全柯里化

总结

  • 柯里化通常保持该函数可以被正常调用且参数数量不足时返回偏函数,即高级柯里化
  • 柯里化通常针对具有固定数量参数的函数

你可能感兴趣的:(javascript编程思想)