JavaScript 函数式编程中的 curry 实现

更新日期: 2020-01-19 阅读: 2.1k 标签: 编程

最近在学习javascript函数式编程,对其中大名鼎鼎的curry十分感兴趣,curry函数可以接受一个函数,我们暂且称之为原始函数,返回的也是一个函数,柯里化函数,这个返回的柯里化函数功能十分强大,他在执行的过程中,不断的返回一个贮存了传入参数的函数,直到触发了原始函数执行的条件。这么说比较概括,那么就举个例子来说明一下:

原始函数:

var add = (x, y) => x + y

柯里化函数:

 var curryAdd = curry(add)

这个add需要两个参数,但是我们的curryAdd执行可以传入更少的参数,当传入的参数少于add需要的参数的时候,add函数并不会执行,curryAdd就会将这个参数记下来,并且返回另外一个函数,这个函数可以继续执行传入参数,我们会有一个变量专门记录传入参数的情况,如果传入参数的总数等于add需要参数的总数,我们就激活了原始参数执行,就会返回我们想要的结果。

// 此时只传入了一个参数 根据判断返回的是一个函数
    var add2 = curryAdd(2)
    // add2 = function(...) {}
// 此时累计传入了两个参数 等于了add需要参数的总和 所以返回的是一个结果
    // 相当于执行了add(2)(3)
    var result = add2(3)
    // result = 5

还是很不错的是吧,好吧,我们的目的是为了写出这个神奇curry函数,而且还要一行写出来,不要着急,先分析一下怎么去写,然后再一步步的优化。

那根据上面的描述,我们看一下curry函数需要什么,首先需要一个变量,用来存下来原始函数的参数个数,我们知道function有一个属性为length,对就是它,我们用limit存下来

    var curry = function(fn) {
         var limit = fn.length
         ...
    }

curry函数要返回一个函数, 这个函数是要执行的,那么问题就是,我们要判断这个函数的执行是否激活了原始函数的执行,问题就出现在传入的参数上面。返回函数还是结果?这的确是一个问题,我们先写返回结果的情况,当传入的参数等于原始函数需要的参数时,我们执行原始函数fn

    var curry = function(fn) {
         var limit = fn.length
         return function (...args) {
             if (args.length >= limit) {
                 return fn.apply(null, args)
             }
         }
    }

否则呢 我们就要返回一个贮存了参数的函数,这里有两点,一是参数的传入历史我们要记录下来,二是这个返回的函数需要做些什么

    var curry = function(fn) {
         var limit = fn.length
         return function (...args) {
             if (args.length >= limit) {
                 return fn.apply(null, args)
             } else {
                 return function(...args2) {

                 }
             }
         }
    }

看出来了吧 我们只需要把返回函数执行的参数累加起来就达到了记录参数传入情况的目的,于是我们想到了concat 对 args.concat(args2), 依次类推,我们返回的函数要做的就是重复做上面的事情,也就是参数为args的函数要做的事情,所以他需要一个名字,不然我们没法执行,我们叫它judgeCurry

所以正如我们所说的,要么返回一个函数,要么执行原始函数。

    var curry = function(fn) {
         var limit = fn.length
         return function judgeCurry (...args) {
             if (args.length >= limit) {
                 return fn.apply(null, args)
             } else {
                 return function(...args2) {
                     return judgeCurry.apply(null, args.concat(args2))                                     
                 }
             }
         }
    }

我们终于写完了这个神奇的curry函数,它真的很强大,配合compose,那真是一个字,爽。

我们的目的还是一行把上面那个函数写出来,一行写?怎么写?对了,用ES6啊,于是一番折腾

var currySingle = fn => judgeCurry = (...args) => args.length >= fn.length ? fn.apply(null, args) : (...args2) => judgeCurry.apply(null, args.concat(args2))

好,我们看一下哪有问题,对了,就是我们为了不用limit参数,用了就得赋值,赋值就不能一行搞定了,就会变成这样

    var currySingle = fn => {
        var limit = fn.length
        var judgeCurry = null
        return judgeCurry = (...args) => args.length >= limit ? fn.apply(null, args) : (...args2) => judgeCurry.apply(null, args.concat(args2))
    }

需要判断参数的时候不断的对fn.length求值,但是fn.length的值是确定的,我们不想每次都求值,但又不想用limit怎么办,有什么办法呢?你一定想到了,立即执行函数!!

var currySingle = fn => ((limit) => judgeCurry = (...args) => args.length >= limit ? fn.apply(null, args) : (...args2) => judgeCurry.apply(null, args.concat(args2)))(fn.length)

不得不感叹javascript的神奇,终于,我们就一行将这个神奇的curry写出来了。

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/8702

相关推荐

在线运行编程网站

学编程的程序员小伙伴越来越多了,在学习的过程中会发现很多知识点如果不在工作中运用或者手写带验证的话,很容易忘记。任何技能的掌握都是需要不断练习的。在此整理一些在线运行编程的网站。

前端的编程软件哪些比较好用?

推荐8款最好用的前端开发工具供美工或者前端开发人员使用,当然若你是NB的全栈工程师也可以下载使用。Web前端开发最常见的编程软件有以下几种: 在前端开发中,有一个非常好用的工具,Visual Studio Code,简称VS code

程序员的笔记,编程写软件学到的 7 件事

如果你真的做出了一些东西,在面对那些令人眼花缭乱的理论知识,或是和你相似甚至比你做的更糟糕的人时大可不必谦虚。在一天结束之时,正是那些在战壕中的开发者——构建、测试和开发了代码的人,真正做了事情。

十大编程语言榜单

如果你是软件开发领域的新手,那么你会想到的第一个问题是“如何开始?”编程语言有数百种可供选择,但是你怎么发现哪个最适合你,你的兴趣和职业目标又在哪里呢?选择最佳编程语言以学习的最简单方法之一,是通过市场反响、技术趋势的发展…

Blockly - 来自Google的可视化编程工具

Google Blockly 是一款基于Web的、开源的、可视化程序编辑器。你可以通过拖拽块的形式快速构建程序,而这些所拖拽的每个块就是组成程序的基本单元。可视化编程完成

感觉自己不适合做程序员,什么样的人不适合做程序员?

学习是一件艰苦的事情。很多人想要成为程序员,在学习编程的过程中,面对各种 bug 和源源不断的问题,有时会对自己是否适合编程这一问题产生困扰。在教学的过程中,他总结出了不适合做程序员的十个特征

CSS并不是真正的编程语言

每隔几个月就会出现一篇文章表明:CSS并不是真正的编程语言。以编程语言的标准来说,CSS过于困难。使用这门语言会很有创造性:事实确实如此,CSS不同于传统的编程,且具有缺陷,同任何标准化编程语言相比

自学编程的网站有那些?

如今,很大一部分人在学习编程的道路上都选择自学,但都苦于找不到适合自己的学习资源,今天为大家介绍11个免费的自学编程的网站,为大家提供一些帮助。很多人自学编程,都会通过w3school,你可以通过它学习所有的网站建设基础教程

无码编程:无代码软件开发大行其道

代码是大多数软件程序和应用程序的骨干。每行代码充当一条指令:采用一种逐步性的逻辑机制,以便计算机、服务器和其他机器执行操作。想创建那些指令,就要知道如何编写代码,这项宝贵的技能有时很吃香。

自学编程的六个技巧总结

这些事情可以帮助新手在他们漫长的旅程中学习编程。我知道我还有更多东西需要学习,并将继续学习如何永远地学习。最重要的事情说三遍,请继续,不要放弃,不要放弃,不要放弃。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!