js之柯里化与反柯里化

151 阅读1分钟

前言

柯里化函数,一个接受参数后不立刻执行,而是返回一个接受剩余参数的函数
反柯里化函数,把别人的函数拿来,改装改装,改装后变成一个更普适性的函数,可以被不同的对象使用

柯里化

例如,实现`sum(1,2)(3)(4,5)()`,然后输出参数总和 **关键点**: 1. `sum`函数可以无限传入参数,且传入参数后,不立刻执行,而是把参数先存储下来 2. 当传入参数为空的时候,触发执行
    function curring(fn) {
        // 存储参数的容器
        let allArgs = [];
        return function next() {
            // 将参数转换为数组
            let args = [].slice.call(arguments);
            if (args.length > 0) {
                // 存储参数
                allArgs = allArgs.concat(args);
                // 返回可以接受剩余参数的函数
                return next;
            } else {
                // 参数为空,执行结果
                return fn.apply(null, allArgs);
            }
        }
    }

    // 初始柯里化函数
    let sum = curring(function () {
        return Object.values(arguments).reduce((a, b) => a + b);
    });
    
    sum(1,2)(3)(4,5)();       //  15

如果要实现sum(1,2)(3)(4,5),就需要另外设定触发条件,可以使用toStringvalueOf

    function curring(fn) {
        let allArgs = [];
        function next() {
            let args = [].slice.call(arguments);
            allArgs = allArgs.concat(args);
            return next;
        }
        next.toString = function () {
            return fn.apply(null,allArgs);
        };
        next.valueOf = function () {
            return fn.apply(null,allArgs);
        };
        return next;
    }
     // 初始柯里化函数
    let sum = curring(function () {
        return Object.values(arguments).reduce((a, b) => a + b);
    });
    
    sum(1,2)(3)(4,5).toString();       //  15

反柯里化

例,我们要实现`push([1,2,3],4,5,[6,7])`,输出结果为`[1,2,3,4,5,[6,7]]`,通常实现方法应该是`[1,2,3].push(4,5,[6,7])`,我们现在可以用反柯里化换成我们要实现的那个形式。 ``` Function.prototype.uncurring = function () { // self指向push let self = this; return function () { // 取出第一个参数,即添加对象 let obj = Array.prototype.shift.call(arguments); // 相当于obj.push(arguments) return self.apply(obj,arguments); } };
let push = Array.prototype.push.uncurring();

let arr = [1,2,3];
push(arr,4,[7,8],6);
console.log(arr);