资讯专栏INFORMATION COLUMN

函数柯里化(curry)

import. / 1865人阅读

摘要:还是上面函数的例子,我们希望实现下面的形式在下一节具体实现部分应用只传递了第一个参数分析上面的代码可知,实现部分应用的关键是部分应用的返回结果是一个新的函数该函数可以被传入其他参数再次调用柯里化现在进入正题,前面讲完了部分应用。

前言

(话不多说,填之前的坑)

正文 引子-从apply说函数应用

在js里,我们对于function的用法,可能大部分情况下都还是处于调用,形如

function add(x, y) {
    return x + y
}
console.log(add(1, 2)) //函数调用 返回3

但是有一个apply()函数,使我们拥有另一种方式来应用函数,例如

function add(x, y) {
    return x + y
}
console.log(add.apply(null, [1, 2])) //返回3

apply的第一个参数为null时,this指向全局对象(忘记请自行查阅查mdn),在上面这个例子里,通过apply来应用函数的时候,效果和调用函数完全一致。

部分应用

从前文可知,函数调用就是让一个参数集合(前面的[1,2])应用到函数(前文的add函数)中,那部分应用就是考虑只传递部分参数,而非所有参数。 还是上面add函数的例子,我们希望实现下面的形式(在下一节具体实现):

var newAdd = add.apply(null,[1])//部分应用 只传递了第一个参数
newAdd.apply(null,[2]) //3

分析上面的代码可知,实现部分应用的关键是:部分应用的返回结果是一个新的函数,该函数可以被传入其他参数再次调用

柯里化(curry)

现在进入正题,前面讲完了部分应用。curry化的含义,就是使函数理解并处理部分应用的过程

继续按照上文的思路实现add函数的curry化:

function add(x, y) {
    // 如果只传递部分参数,则部分应用,返回一个新的函数
    if (y === undefined) {
      return function (y) {
        return x + y
      }
    }
    return x + y //如果传递所有参数,直接完全应用
}
//运行前一节代码
var newAdd = add.apply(null, [1])
console.log(newAdd.apply(null, [2])) //3
console.log(newAdd.apply(null, [5])) //6

上述代码已经实现了前一节的要求,可以看到curry的结果就是:经过一次curry的newadd函数,变成一个与1求和的函数,接应用的时候只传递一个参数,都能得到对应的结果,同时也可以看出这个curry太局限。接下来我们就要考虑,如何实现通用的curry函数

通用curry函数

先回忆前面的过程,来思考curry一个函数的实现步骤:

保存调用curry函数时传入的参数,返回一个新函数(即柯里化执行结果)

结果函数在被调用后,要让新的参数和旧的参数一起应用的入参函数中

注:入参函数-要被curry的函数,结果函数-被curry之后的函数*

文字比较抽象,可以直接看实现在回来看过程:

  function commonCurry(fn) {
    var slice = Array.prototype.slice,
      storedArgs = slice.call(arguments, 1) //使用slice是为了把arguments转换成真正的数组,剥离此处第一个参数,是因为第一个参数是fn
    return function () {
      var newArgs = slice.call(arguments), //新传入的参数
        args = storedArgs.concat(newArgs)
      return fn.apply(null, args)
    }
  }

  //使用举例
  function add(a, b) {
    return a + b
  }
  var newAdd = commonCurry(add, 10)
  console.log(newAdd(5))
  
  // 多个参数
  function add2(a, b, c, d) {
    return a + b + c + d
  }
  var newAdd2 = commonCurry(add2, 10, 10)
  console.log(newAdd2(5, 4))//29
  
  // 多次curry
  var newAdd3 = commonCurry(newAdd2, 10)
  console.log(newAdd3(10))//40
小结

之后会尝试以更简洁明了的方式来写文章。如果内容有错误的地方欢迎指出(觉得看着不理解不舒服想吐槽也完全没问题);如果对你有帮助,欢迎点赞和收藏,转载请征得同意后著明出处,如果有问题也欢迎私信交流,主页添加了邮箱地址。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/96729.html

相关文章

  • 高级函数技巧-函数柯里

    摘要:如果你对函数式编程有一定了解,函数柯里化是不可或缺的,利用函数柯里化,可以在开发中非常优雅的处理复杂逻辑。同样先看简单版本的方法,以方法为例,代码来自高级程序设计加强版实现上面函数,可以换成任何其他函数,经过函数处理,都可以转成柯里化函数。 我们经常说在Javascript语言中,函数是一等公民,它们本质上是十分简单和过程化的。可以利用函数,进行一些简单的数据处理,return 结果,...

    shixinzhang 评论0 收藏0
  • JavaScript 函数式编程技巧 - 柯里

    摘要:作为函数式编程语言,带来了很多语言上的有趣特性,比如柯里化和反柯里化。在一些函数式编程语言中,会定义一个特殊的占位变量。个人理解不知道对不对延迟执行柯里化的另一个应用场景是延迟执行。不断的柯里化,累积传入的参数,最后执行。作为函数式编程语言,JS带来了很多语言上的有趣特性,比如柯里化和反柯里化。 这里可以对照另外一篇介绍 JS 反柯里化 的文章一起看~ 1. 简介 柯里化(Currying)...

    edgardeng 评论0 收藏0
  • js 扩展 -- currying 柯里函数

    摘要:里也有柯里化的实现,只是平时没有在意。如果函数柯里化后虽然生搬硬套,不过现实业务也会有类似场景。 柯里化 先解释下什么是 柯里化 在计算机科学中,柯里化(英语:Currying),又译为卡瑞化或加里化,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。 js 里也有柯里化的实现,只是平时没有在意。先把原文简介贴...

    Pocher 评论0 收藏0
  • JS中的柯里

    摘要:作为函数式编程语言,带来了很多语言上的有趣特性,比如柯里化和反柯里化。个人理解不知道对不对延迟执行柯里化的另一个应用场景是延迟执行。不断的柯里化,累积传入的参数,最后执行。 作为函数式编程语言,JS带来了很多语言上的有趣特性,比如柯里化和反柯里化。 这里可以对照另外一篇介绍 JS 反柯里化 的文章一起看~ 1. 简介 柯里化(Currying),又称部分求值(Partial Evalu...

    Hancock_Xu 评论0 收藏0
  • JS中的柯里 及 精巧的自动柯里实现

    摘要:笑中自动柯里化的精巧实现柯里化是函数式编程中很重要的一环,很多函数式语言都会默认将函数自动柯里化。 什么是柯里化? 在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。这个技术由 Christopher Strachey 以逻辑学家 Haskell Curry 命名的,尽管...

    moven_j 评论0 收藏0
  • JavaScript专题之函数柯里

    摘要:一个经常会看到的函数的实现为第一版我们可以这样使用或者或者已经有柯里化的感觉了,但是还没有达到要求,不过我们可以把这个函数用作辅助函数,帮助我们写真正的函数。 JavaScript 专题系列第十三篇,讲解函数柯里化以及如何实现一个 curry 函数 定义 维基百科中对柯里化 (Currying) 的定义为: In mathematics and computer science, cu...

    zhangfaliang 评论0 收藏0

发表评论

0条评论

import.

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<