Skip to content

柯里化是一个超纲内容,也很难,读者可以不用看,柯里化实际上就是柯里化函数,属于函数式编程的范畴,柯里化函数的作用就是:固定一个函数的某些参数,得到该函数的剩余参数的一个新函数,如果没有剩余参数,则调用。

这个概念非常抽象,这里从使用者的角度出发看一下,假设有一个别人写好的函数 A,这个函数接受两个参数 a 和 b,但是在我这个场景下,参数 a 是固定不变的,此时就可以使用柯里函数将这个函数 A 改造一下,把它第一个参数固定下来,让他只能接受一个参数,简单而言,柯里化函数就是用来将原函数的一些参数固定,返回一个新的函数,这个新的函数如果参数足够,就会直接调用,如果参数不够,就会再次柯里化固定一些参数。

js
        /**
         * curry函数用于将多参数函数转换为单参数函数,以便逐步传递参数。
         * @param {Function} fn 需要被转换的多参数函数。
         * @returns {Function} 返回一个逐步接受参数并最终执行原函数的单参数函数。
         */
        function curry(fn) {
            var args = [].slice.call(arguments, 1); // 将除了第一个参数外的所有参数转换为数组。
            var that = this; // 保存当前执行上下文。
            return function () {
                var currentArg = Array.from(arguments); // 将当前调用传递的参数转换为数组。
                var totalArg = args.concat(currentArg); // 将之前保存的参数和当前参数合并。
                if (totalArg.length < fn.length) { // 如果累计参数数量小于原函数参数数量,继续递归。
                    totalArg.unshift(fn) // 将原函数添加到参数数组的开头。
                    return that.curry.apply(null, totalArg); // 在当前上下文中递归调用curry函数。
                } else { // 如果参数数量足够,执行原函数。
                    return fn.apply(null, totalArg); // 使用apply调用原函数,确保所有参数被正确传递。
                }
            }
        }
        /**
         * 用于测试的函数,接受三个参数并求和。
         * @param {number} a 第一个参数。
         * @param {number} b 第二个参数。
         * @param {number} c 第三个参数。
         * @returns {number} 参数之和。
         */
        function test(a, b, c) {
            console.log(a + b + c);
        }
        // 直接调用test函数,传入全部参数。
        test(2, 3, 4);
        // 将test函数通过curry转换,预先传入第一个参数1。
        var test1 = curry(test, 1);
        // 使用test1,传入第二个参数2。
        test1(2, 3);
        // 上述调用相当于test(1, 2, 3),现在将test1的返回结果(即curried的test函数)赋值给test2。
        var test2 = test1(5);
        // 调用test2,传入最后一个参数6。全部参数已传入,将执行原test函数。
        test2(6);
  • 函数curry接受一个参数fn,代表要进行柯里化的函数。
  • 在函数内部,首先通过arguments对象和slice方法获取除第一个参数外的所有参数,并将其保存在args数组中。
  • 然后,使用this保存当前上下文,并返回一个新的函数。
  • 这个新的函数接受任意数量的参数,并将其保存在currentArg数组中。
  • 接着,将args和currentArg数组进行合并,得到一个新的数组totalArg。
  • 如果totalArg的长度小于fn的参数长度,则将fn放入totalArg数组的开头,并通过curry方法递归调用自身,并使用apply方法将null作为上下文传入,将totalArg作为参数传入。
  • 如果totalArg的长度大于等于fn的参数长度,则通过apply方法将null作为上下文传入,将totalArg作为参数传入,并执行fn函数。

实际上,柯里化的作用就是固定参数,在函数式编程中,柯里化函数的作用就是把一些通用函数的参数变少,可以更加方便我们使用。

以笔记为镜,可以知得失