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

时间: 2017-12-01阅读: 583标签: 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?”

来源:众成翻译


js 实现栈和队列

js实现栈或者队列有两种方式: 1.数组:数组本身提供栈方法(push,pop),队列方法(push,shift)。 2.链表:构造链表结构,说白了就是链表的插入(尾插),移除(栈:末尾节点移除,队列:头结点移除)

javascript的Object. hasOwnProperty方法

hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中(非继承属性)是否具有指定的属性,如果 object 具有带指定名称的属性,则 hasOwnProperty 方法返回 true,否则返回 false。

js常见知识点整理总结

一些常用的JavaScript 知识点整理,包括:两个函数是否等价、NaN是什么?它是什么类型?如何检测一个变量是否是NaN?作用域相关问题?js小数计算不准确的bug,js算法/思路相关,js类型强制转换

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