前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JS函数无限柯里化

JS函数无限柯里化

作者头像
kifuan
发布2022-10-24 16:39:38
2.4K0
发布2022-10-24 16:39:38
举报
文章被收录于专栏:随便写写-kifuan

源码

点击这里前往Github查看本文源码,文件名中有arrow-func的就是用箭头函数实现的版本。

不用箭头函数的实现

网上看到很多用箭头函数的版本,在看不懂的时候非常的眼花。

所以在这里我选择先用纯粹的function配合arguments分析完原理,再过渡到轻量级的箭头函数。下面给出最原始的实现:

代码语言:javascript
复制
function curry(f, ...savedArgs) {
    return function() {
        const totalArgs = [...savedArgs, ...arguments]
        if (totalArgs.length >= f.length) {
            return f(...totalArgs)
        }
        return curry(f, ...totalArgs)
    }
}

步骤如下:

  1. 我们在定义时就做了一个手脚,那就是留了一个可变长参数savedArgs
  2. 第3行定义了一个totalArgs总参数数组,它包含着外层保存下来的savedArgs以及这个函数本身的arguments
  3. 第4行判断了总参数totalArgs与原始函数的长度f.length,如果参数数量足够,那就直接调用原始函数f并且返回结果
  4. 第7行就是如果说参数还不够,那就把总参数totalArgs一并传给curry包装起来,等待下一次调用

那么我们可以试一下好不好用,读者也可以打开控制台试一试:

代码语言:javascript
复制
const add = (a, b, c) => a + b + c


curry(add)(1)(2)(3)
curry(add)(1, 2)(3)
curry(add)(1)(2, 3)
curry(add)(1, 2, 3)

以下结果全都是6,符合我们的要求。

箭头函数轻量级实现

众所周知,箭头函数是一种轻量级的函数,它不像function那样会有冗余的字段。

那么分析完原理之后就较为简单了:

代码语言:javascript
复制
const curry = (f, ...outer) => {
    return (...inner) => {
        if (outer.length + inner.length >= f.length) {
            return f(...outer, ...inner)
        }
        return curry(f, ...outer, ...inner)
    }
}

我觉得这已经够好了,但是如果你说还能压缩的话也对,它可以写成一行:

代码语言:javascript
复制
const curry = (f, ...outer) => (...inner) => outer.length + inner.length >= f.length ? f(...outer, ...inner) : curry(f, ...outer, ...inner)

但是我觉得正常人类是看不大懂这玩意的,不推荐!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 源码
  • 不用箭头函数的实现
  • 箭头函数轻量级实现
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档