js多箭头和函数柯里化
高阶函数
高阶函数是至少满足以下条件之一的函数:
- [ ] 函数可以作为参数被传递;
- [ ] 函数可以作为返回值输出。
举几个例子,js中的排序函数sort,就是函数作为参数的一个高阶函数。
1 | // 从小到大 |
js中判断数据类型的,就是函数作为返回值。
1 | const isType = function(type) { |
函数柯里化
函数柯里化(function currying)概念最早是由俄国数学家Moses Schönfinkel发明出来,后由数学家Haskell Curry丰富和发展,currying由此得名。
currying又称部分求值。一个currying函数首先会接收一些参数,接受了这些参数之后,该函数并不会立即求值,而是继续返回另一个函数,刚才传入的参数在函数形式的闭包中
被保存起来。待到函数真正需要求值的时候,之前传入的所以参数都会被一次性用于求值。
下面来看一个最简单的计费函数:
1 | let totalCost = 0; |
通过这段代码我们可以计算出某时间段的费用,然而这段代码有两个弊端,一是在外部暴露了一个全局变量,容易导致变量污染;二是我们并不关心每天花费多少,并不想每次花费都计算一次,而是
希望在最后需要计算时在全部做计算。接下来我们改进代码,用currying实现效果。
1 | let totalCost = (function() { |
多箭头函数
多箭头函数其实就是函数柯里化的es6写法,比如我们常见的求和函数,采用高阶函数的写法:
1 | function sum(a){ |
采用es6对箭头的写法等价于:let sum = a => b => a + b;
wiki 的柯里化定义:
把接受多个参数的函数变换成接受一个单一参数的函数,并且返回(接受余下的参数而且返回结果的)新函数的技术
简单的理解就是,把第一个参数变量存在了函数(闭包)里面,然后需要n
个参数就变成了需要n-1
个参数就可以调
用函数了。例如上面的案例:
1 | let sum = a => b => a + b; |
本来完成sum操作应该是:
1 | let sum = (a, b) => x + y; |
它需要俩参数,而上面的sum
函数完成同样操作只需要一个参数,这在函数式编程中广泛应用。
详细解释一下,就是sum
函数等价于有了x
这个闭包变量的y => x + y
函数。
也因此当a = 2
,然后再调用sum2(5)
时:
1 | sum(5) ==== 2 + 5 |
函数柯里化有两个功能:一是可以惰性求值;二是可以提前传递部分参数。