what?函数还有分期付款

思考

一个函数有多个形参,可以传入多个实参。例如以下这段函数

js 复制代码
function add(a,b,c){
    return a+b+c;
}

我们是如何调用这个函数的?

js 复制代码
add(1,2,3)//6

我们直接向函数中一次性传入三个形参,就像买东西一样,一次性付款,这样我们就成功地调用了add函数

但是如果我想分期付款呢?我将要传入的参数分3次分别传入,例如:

js 复制代码
add(1)(2)(3)

我还要让这个函数被成功地调用起来,我们该如何实现???

开始

1. 构想

在动手写代码之前,我们先来构想一下,我们需要用到什么来完成我们的代码。

  • Function.length

我们将多次传入参数,当我们传入足够的参数以后,才开始调用函数,所以我们究竟该怎么知道要传入几个参数呢?我们使用Function.length来获取

js 复制代码
console.log(add.length)//3
  • 闭包

我们是将参数分批传入函数的,所以我们还得在最后拿到我之前传入的参数,例如:

js 复制代码
add(1)(2)(3)

当我传入(3)的时候,我必须还得拿到(1)(2),那么我们就得使用到闭包了...有不太懂闭包的掘友们可以去看我之前的文章(深入探讨:闭包的神秘面纱 - 掘金 (juejin.cn))

2.动手

参考上面的思路,我们来完成我们的代码

js 复制代码
function curry(fn){
    let judge = (...args)=>{
        if(args.length === fn.length) return fn(...args) //退出条件
        return (...arg) => judge(...args,...arg)
    }
    return judge
}
const curryAdd = curry(add)
console.log(curryAdd(1)(2)(3));

当我们调用 curry 函数并传入一个函数 fn 时,curry 函数会返回一个新的函数 judge。这个 judge 函数可以接受任意数量的参数。

judge 函数内部,我们使用一个变量 args 来存储已经传入的参数。当我们调用 judge 函数并传入一些参数时,这些参数会被添加到 args 数组中。

然后,我们检查 args 数组的长度是否与原始函数 fn 的参数个数相等。如果相等,说明我们已经传入了所有需要的参数,此时我们直接调用原始函数 fn 并将 args 数组作为参数传递进去,并返回结果。

如果 args 数组的长度不等于 fn 的参数个数,那么我们就返回一个新的函数。这个新函数也是 judge 函数,并接受剩余的参数。我们使用扩展运算符 ...args 数组和剩余的参数合并起来,并递归调用 judge 函数。这样就可以继续接受更多的参数,直到参数个数满足条件。

看结果:

收工

这个方法也叫函数的柯里化,函数柯里化是一种将多个参数的函数转化为一系列只接受单个参数的函数的过程。这种实现方式可以使函数变得更加灵活,可以逐步传递参数,使代码更易读和可维护。

相关推荐
reembarkation13 分钟前
使用pdfjs-dist 预览pdf,并添加文本层的实现
前端·javascript·pdf
reembarkation15 分钟前
vue-pdf 实现blob数据的预览
javascript·vue.js·pdf
李明卫杭州27 分钟前
JavaScript中的dispatchEvent方法详解
javascript
KenXu28 分钟前
F2C-PTD工具将需求快速转换为代码实践
前端
月阳羊29 分钟前
【硬件-笔试面试题-95】硬件/电子工程师,笔试面试题(知识点:RC电路中的时间常数)
java·经验分享·单片机·嵌入式硬件·面试
给月亮点灯|37 分钟前
Vue3基础知识-setup()、ref()和reactive()
前端·javascript·vue.js
芜青38 分钟前
【Vue2手录12】单文件组件SFC
前端·javascript·vue.js
冷冷的菜哥38 分钟前
react实现无缝轮播组件
前端·react.js·typescript·前端框架·无缝轮播
hrrrrb1 小时前
【Python】字符串
java·前端·python
阿笑带你学前端1 小时前
Supabase云同步架构:Flutter应用的数据同步策略
前端