带有 rest 运算符的通用 curry 函数

Generic curry function with rest operator

我现在正在学习 js 中的柯里化,尤其是如何创建通用柯里化函数。我找到了一个这样的例子:

function curry(fn) {
    return function curried(...args) {
        console.log(args)
        if (args.length < fn.length) {
            return curried.bind(null, ...args);
        }
        return fn.apply(null, args);
    };
}

这行得通,当我给这个 curry 函数一个带有 3 个参数的函数时:

function add (x, y, z) {return x + y + z;}
var addCurried = curry(add);

然后我这样称呼它:

console.log(addCurried(1)(2)(3));

然后我得到 4 个日志:

[1]

[1,2]

[1,2,3]

6

我知道每次调用 addCurried 时,我们感谢“curried.bind”返回一个新函数,它递归调用 curried 函数,而这又 returns 一个新函数等等.这就是为什么我们有 3 个调用 3 个参数。我不明白内部柯里化函数中的“args”参数如何在元素中不断增加?我们不对“args”数组做任何推送。顺便说一下,没有其余运算符相同的咖喱函数:

function curry(fn){
    return function curried() {
        var args = Array.prototype.slice.call(arguments);

        console.log(args);

        if (args.length < fn.length) {
            return function (a) {
                var newArgs = [].concat(args, a);
                return curried.apply(null, newArgs);
            }
        }
        return fn.apply(null, args);
    }
} 

对我来说完全清楚,因为我们执行“var newArgs = [].concat(args, a);”和 save/push 将参数手动放入数组中。这就是为什么每次我们调用内部 curried 函数时,我们都会多获得一个参数,并且我们的“args”不断增加。

所以我的问题是:如何在通用 curry 函数“args”参数的其余运算符版本中获取新元素?这是怎么回事?

当您通过 curried.bind(null, ...args) 将 args 传递给 bind 时,新函数将 ...args 作为参数添加到传递给它的任何参数之前。

来自the MDN docs

arg1, arg2, ...argN Optional
Arguments to prepend to arguments provided to the bound function when invoking func.

function foo(...args) {
  return args;
}

console.log(foo(1)); // [1]

// prepends 2 to args
const bar = foo.bind(null, 2);

console.log(bar(1)); // [2, 1]

// prepends 3 to args, after the already-bound 2
const baz = bar.bind(null, 3);

console.log(baz(1)); // [2, 3, 1];