SOURCE

/**
 * 柯里化函数
 * 支持多次调用
 * 支持每次调用传入不等量参数
 * 支持最终返回非函数结果
 */

// function add() {
//     let arg = Array.prototype.slice.call(arguments);
//     function _add() {
//         arg = arg.concat(Array.prototype.slice.call(arguments));
//         return _add;
//     }
//     _add.toString = function() {
//         return arg.reduce(function(a, b) {
//             return a + b;
//         });
//     }
//     return _add;
// }

// console.log(add(1, 2, 3)(4)(5,3));

// console.log(add(1)(2)(3)(4));
// console.log(add2(1)(1, 2 , 3)(2));

function currying(fn, defaultArgs) {
    // 获取传入函数参数总长度
    const len = fn.length || 0;
    // 利用闭包存储参数集
    let args = defaultArgs || [];
    // 备份this
    const self = this;

    // 返回一个函数
    return function() {
        // 将函数的参数转化为数组
        const _args = Array.prototype.slice.call(arguments);
        // 将_args合并到args中
        Array.prototype.push.apply(args, _args);
        // 如果参数总和少于原来函数的参数长度
        if (args.length < len) {
            // 返回currying以供继续调用
            return currying.call(self, fn, args);
        }

        // 调用传入函数并且传入所有参数
        return fn.apply(self, args);
    }
}

function add (x, y, z) {
    return Array.prototype.slice.call(arguments).reduce(function(a, b) {
        return a + b;
    });
}

function message(name, age, text) {
    console.log(`My name is ${name}, age is ${age}, my log is ${text}`);
}

const curryAdd = currying(add);
console.log(curryAdd(1, 2)(4));

const curryMessage = currying(message);
curryMessage('lili', 18)('haha');
console 命令行工具 X clear

                    
>
console