JS手写代码篇---手写函数柯里化
13、手写函数柯里化
它将一个接受多个参数的函数转换为一系列只接受一个参数的函数
举个例子:
function add(a, b) {return a + b;}console.log(add(2, 3)); // 输出:5// 柯里化后:function curriedAdd(a) {return function (b) {return a + b;};}const add2 = curriedAdd(2); // 固定第一个参数为 2console.log(add2(3)); // 输出:
柯里化
- 传入:一个函数,但是有多个参数
- 目的:就是把多个参数进行链式调用
let currying = function (func) {// 参数// let args = [];//这样的话,每次调用currying,都会指向第一次的args// 返回函数进行链式调用,,也需要传递参数return function curried(...args) {// 每次链式调用都应该有自己的参数收集,可以这样递归实现:return function result(...res) {// 当res的长度为0(不调用参数的时候,就代表要执行函数)if (res.length === 0) {return func(...args)} else {// 当在执行函数之前,就要保存参数,进行链式调用args.push(...res);return result;}}}}
进行改进:
// 柯里化函数:传入一个函数let currying = function (func) {// 开始递归返回函数// ...args可以收集函数return function curried(...args) {// 如果参数数量足够,执行原函数// 如果收集的函数参数大于等于了原函数的参数,就可以直接执行了if (args.length >= func.length) {return func.apply(this, args);}// 否则返回一个新函数继续收集参数// 当参数不足时,返回一个新函数继续收集参数// 新函数将之前收集的参数(args)与新传入的参数(newArgs)合并return function (...newArgs) {// 这里就是链式调用return curried.apply(this, args.concat(newArgs));};};};
我写的一些问题:
- 结构复杂:嵌套了两个函数(curried和result),逻辑不够直观
- 参数收集不完整:只收集了第二次及以后的参数,第一次调用的参数没有被收集
- 递归使用不当:result函数的递归调用方式不够优雅
- 链式调用逻辑有误:当传入空参数时才执行函数,这与柯里化的常见实现方式不同