javascript偏函数应用与柯里化的区别

时间: 2017-12-01阅读: 454标签: js知识

很多刚刚了解函数式编程的人会对偏函数应用(partial application)和柯里化(currying)之间的区别感到困惑。实际上,直到现在也很少在 JavaScript 中看到柯里化的实际使用,许多叫curry()的工具函数并不是柯里化函数。它们其实是偏函数!

如果你也不清楚区别,本文会为你梳理清楚,不过让我们搞清楚一些词语:

定义

应用: 将函数应用于参数,以得到返回值的过程。

偏函数应用: 将函数应用于其部分参数的过程。返回的偏函数在之后被使用。也就是说,一个函数接收一个有多个参数的函数,返回一个需要较少参数的函数。偏函数将一到多个参数在内部固定,然后返回新函数,返回的函数接收剩余的参数完成函数的应用。

柯里化: 输入一个有多个参数的函数, 返回一个只接收单个参数的函数。

这有什么关系呢?

James Coglan 的演讲会帮助你理解:

James 讨论的特性依赖于函数类型一致性。函数有类型。举例来说,函数接收函数和数组,返回数组(例如,Function.prototype.map()):

(fn, array) -> array
  • 偏函数应用 会也可能不会有可预期的返回类型

  • 柯里化函数始终返回另一个具有单个参数而其他参数被指定的函数。

James 讨论的重要的东西都依赖于 函数类型一致性。例如他提到 promise 可以帮助程序逻辑抽象对时间的依赖。

Promise 可以做到是因为它提升了你调用的函数,使得其返回类型始终一致:所有返回 promise 的函数返回了相同的类型,这意味着你可以用标准化的方式来使用它们。James 提到了 promise 带来的各种好处。

这种情况下,promise 是 函子(functor) (一个巧妙的词,意思是“可以被映射的东西”,例如,数组。参考:可应用的函子(applicative functor))的容器,可以为处理数据提供标准化的方法,而无需考虑数据的类型。

警告: google 下函数式编程的术语会很吓人,不过相比其学术名称,它们其实很简单。

通过处理 容器 而非 容器中的值,你可以为任何使用 *容器接口 的东西创建很多一般的 到处可以使用的函数

和 promise 类似,*科里化函数返回容器,这提供了相同的接口。具体是指,作为容器的返回函数。你可以继续调用返回的函数,直到所有参数都传入后返回最终的值。

换句话说,柯里化函数时可以提升所有参数的函数,使得可以用标准化的方式处理这些参数。

最常见的使用提升的方式是 函数组合(function composition),例如c(x) = f(g(x))。函数组合将一个函数的返回值传给另一个函数作为参数。由于一个函数只能返回一个值,可以接收返回值的函数必定是一元的。

此外,柯里化函数有内置的迭代器机制:柯里化函数每次应用一个参数,不会做超出一个参数外的工作。调用返回的函数也就是告诉函数来进行下一步处理。

例如,柯里化函数 a(b)(c),不会立即调用 c,可以是这样的:

const next = a(b);
doSomeStuff().then(() => next(c));

你应该对偏函数应用和柯里化的区别,以及为什么要对函数执行柯里化有更清楚的理解了。

柯里化在函数式编程中的最常见的应用是让组合函数变得简单。关于这个话题,可以看 “Master the JavaScript Interview: What is Function Composition?”

来源:众成翻译


JavaScript中的魔幻代理Proxy

什么是 JavaScript 代理?通过 Proxy 我们可以拦截并改变一个对象的几乎所有的根本操作,包括但不限于属性查找、赋值、枚举、函数调用等等。利用 Proxy,我们可以拦截并不存在的属性的读取

适配器在JavaScript中的体现

适配器设计模式在JavaScript中非常有用,在处理跨浏览器兼容问题、整合多个第三方SDK的调用,都可以看到它的身影。适配器模式是一种软件设计模式,允许从另一个接口使用现有类的接口。它通常用于使现有的类与其他类一起工作,而无需修改其源代码。

JavaScript中的循环和作用域

JavaScript有一个特点,也许会让开发者头痛, 是与循环和作用域相关的.const。最简单的方案是用 let 声明、另外一个非常普遍的解决这个问题是使用pre-ES6代码, 同时它被称作即时调用函数表达式(IIFE)

JavaScript中的行为委托

行为委托简单来说就是一种设计模式,不同于传统的构造函数的类式设计。这里每个例子会通过构造函数,class和行为委托来不同实现,不过不会评论class,是否使用class取决于你的观点。

打造自己的JavaScript武器库

作为战斗在业务一线的前端,要想少加班,就要想办法提高工作效率。这里提一个小点,我们在业务开发过程中,经常会重复用到日期格式化、url参数转对象、浏览器类型判断、节流函数等一类函数,这些工具类函数

(...)这三个点在JavaScript中意味着什么?

解释JavaScript中三个点的作用:数组/对象扩展运算符、rest运算符(使用函数的参数时,无论是完全替换参数还是与函数的参数一起替换参数,这三个点也称为rest运算符)

await在forEach不起作用解决

我们知道await这个机制肯定是没问题的,如果真的有问题肯定不会轮到我测出来,那么其实剩下来的问题只能是for遍历的原因了。lodash的forEach和[].forEach不支持await,如果非要一边遍历一边执行await,可使用for-of

你不知道的 js 保留字

先是笼统的说一下有什么保留字,保留字的话根据犀牛书的划分,可有分为以下几类:基础保留字、严格模式下的保留字、严格模式下的不完全保留字、ECMAScript3的保留字、ECMAScipt 5 的保留字、全局变量和函数

js实现获取手机相册并上传

当初有很多人说使用form方法将文件封装来上传,可是因为要照顾到从相机中选择图片,所以一直没有去做。 后来看到了Uploader的方法来传文件,感觉自己找到了 。是使用plus.uploader来完成的

js中offset、scroll、event、client的区别和使用

用一句话概述:offset用于获取元素的实际显示尺寸 , scroll用于获取滚动后全部尺寸 , client用于获取不包括滚动条的实际显示尺寸,event用于获取鼠标的坐标位置。下面就详细介绍它们之间的使用和区别