资讯专栏INFORMATION COLUMN

柯里化的理解和实现

hsluoyz / 1274人阅读

摘要:阅读学习专题之函数柯里化函数式编程指南对柯里化的理解很多人对于柯里化的理解仅仅停留在复用参数上。使用柯里化的场景想要实现某个操作逻辑。换句话说,柯里化将输入的函数和参数进行绑定,返回绑定后的函数,返回的函数期待剩余的参数。

阅读学习

JavaScript专题之函数柯里化
JS 函数式编程指南

对柯里化的理解

很多人对于柯里化的理解仅仅停留在“复用参数”上。但我认为函数式编程思想更重要作用的是:解除函数对执行时参数的依赖,增强函数的泛化能力,让函数仅仅包含“纯粹的操作逻辑”,这些操作逻辑要用在什么样的输入上,使用函数时再决定。

使用柯里化的场景:

想要实现某个操作逻辑。(举一个最简单的例子,从对象中取出某个属性的值)

确认这个操作的输入。(在这个例子中,输入是对象和属性key)

将操作的输入作为函数的参数,解除函数实现对【参数的具体值】的依赖。(function getProp(obj, key)

在函数体中,对这些参数执行一系列操作,实现逻辑。(function getProp(obj, key) { return obj[key]; }

得到的函数就仅仅封装了“操作逻辑”,函数对于操作的输入不做任何假设,因此函数的泛化能力很强,可以处理任何合法的输入。(在这个例子中,getProp可以从任何对象中获取任何属性)

“不做任何假设”的说法其实不太准确,比如说getProp就假设了obj参数必须是对象,但这种假设是“完成操作逻辑”的必要要求,“不做任何多余的假设”更准确一些。我在这里使用更绝对的语气,是为了增强自己对这个观点的印象。

当用户使用这个函数封装的操作逻辑时,调用这个函数,并且需要在参数中提供操作的输入。函数执行完以后,返回操作的输出。可以将函数看作一个黑盒子,给什么输入就会返回对应的输出,函数本身是“无状态”的。(在这个例子中,getProp(obj1, "key1")getProp(obj2, "key2"),函数能适应任何合法的输入,不管调用多少次,不管传入什么参数,函数的操作逻辑都不会改变)

通过柯里化,可以在真正执行函数之前先确定某些参数。换句话说,柯里化将输入的函数和参数进行“绑定”,返回绑定后的函数,返回的函数期待剩余的参数。(比如说,我们经常要从Array的原型中获取方法,let getPropFromArrProto = curry(getProp, Array.prototype);通过这个新的函数就能直接从Array.prototype中获取属性)

实现
function curry(fn, ...priorArgs) {
  const length = fn.length;
  return function judge(...restArgs) {
    return priorArgs.length + restArgs.length >= length
      ? fn.call(this, ...priorArgs, ...restArgs)
      : function (...args) { return judge.call(this, ...restArgs, ...args); }
  }
}

// 测试代码
var fn = curry(function (a, b, c, d) {
  console.log([a, b, c, d]);
  return [a, b, c, d];
}, "p");

fn("a", "b", "c") // [ "p", "a", "b", "c" ]
fn("a", "b")("c") // [ "p", "a", "b", "c" ]
fn("a")("b")("c") // [ "p", "a", "b", "c" ]
fn("a")("b", "c") // [ "p", "a", "b", "c" ]

其中,

priorArgs.length + restArgs.length >= length
      ? fn.call(this, ...priorArgs, ...restArgs)
      : function (...args) { return judge.call(this, ...restArgs, ...args); }

它的意思是,如果已经接受的参数数量不少于fn(被柯里化的函数)期待的参数数量,就调用fn并返回结果。
否则,返回一个新的函数,这个函数期待剩余的参数。
调用这个新函数会再次进行参数数量的判断,如果已经接受的参数数量不少于fn(被柯里化的函数)期待的参数数量,就调用fn并返回结果,否则返回一个新的函数……以此类推。

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

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

相关文章

  • 「前端面试题系列6」理解函数的柯里

    摘要:原题如下写一个方法,当使用下面的语法调用时,能正常工作这道题要考察的,就是对函数柯里化的理解。当参数只有一个的时候,进行柯里化的处理。这其实就是函数柯里化的简单应用。 showImg(https://segmentfault.com/img/bVbopGm?w=620&h=350); 前言 这是前端面试题系列的第 6 篇,你可能错过了前面的篇章,可以在这里找到: ES6 中箭头函数的...

    liaorio 评论0 收藏0
  • 前端进击的巨人(五):学会函数柯里化(curry)

    摘要:函数柯里化是把支持多个参数的函数变成接收单一参数的函数,并返回一个函数能接收处理剩余参数,而反柯里化就是把参数全部释放出来。但在一些复杂的业务逻辑封装中,函数柯里化能够为我们提供更好的应对方案,让我们的函数更具自由度和灵活性。 showImg(https://segmentfault.com/img/bVburN1?w=800&h=600); 柯里化(Curring, 以逻辑学家Has...

    chengtao1633 评论0 收藏0
  • 前端基础进阶(八):深入详解函数的柯里

    摘要:函数被转化之后得到柯里化函数,能够处理的所有剩余参数。因此柯里化也被称为部分求值。那么函数的柯里化函数则可以如下因此下面的运算方式是等价的。而这里对于函数参数的自由处理,正是柯里化的核心所在。额外知识补充无限参数的柯里化。 showImg(https://segmentfault.com/img/remote/1460000008493346); 柯里化是函数的一个比较高级的应用,想要...

    kk_miles 评论0 收藏0
  • 从一道面试题认识函数柯里

    摘要:函数柯里化在函数式编程中,函数是一等公民。函数柯里化的主要作用和特点就是参数复用提前返回和延迟执行。可能在实际应用场景中,很少使用函数柯里化的解决方案,但是了解认识函数柯里化对自身的提升还是有帮助的。 最近在整理面试资源的时候,发现一道有意思的题目,所以就记录下来。 题目 如何实现 multi(2)(3)(4)=24? 首先来分析下这道题,实现一个 multi 函数并依次传入参数执行,...

    13651657101 评论0 收藏0
  • JavaScript函数式编程,真香之组合(一)

    摘要:组合的概念是非常直观的,并不是函数式编程独有的,在我们生活中或者前端开发中处处可见。其实我们函数式编程里面的组合也是类似,函数组合就是一种将已被分解的简单任务组织成复杂的整体过程。在函数式编程的世界中,有这样一种很流行的编程风格。 JavaScript函数式编程,真香之认识函数式编程(一) 该系列文章不是针对前端新手,需要有一定的编程经验,而且了解 JavaScript 里面作用域,闭...

    mengbo 评论0 收藏0

发表评论

0条评论

hsluoyz

|高级讲师

TA的文章

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