Open zhaoqize opened 6 years ago
对于函数柯里化之前就了解过,大概知道是个什么东西。 最近在读Vue源码的时候,看到了 cached 函数的使用,让我觉得这个代码写的挺有意思,于是在sf发问,看了 @sunyongjian 回答,于是又绕到了 柯里化 和 高阶函数上。
cached
@sunyongjian
柯里化
高阶函数上
维基中有对柯里化的定义:在计算机科学中,柯里化(英语:Currying),又译为卡瑞化或加里化,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。
卡瑞化
加里化
着重看 多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数
var foo = function(a) { return function (b) { return function (c) { return a+b+c; }; }; };
使用
foo(1) // f (b) { return function(c) { return a+b+c } } foo(1)(2) // f (c) { return a+b+c } foo(1)(2)(3) // 6
其实就是逐渐消元的过程。知乎上也有类似的问题,具体见:如何理解functional programming里的currying与partial application
上面的例子虽然解释了什么是柯里化,但是还不通用,因为 参数个数 理论上是无法估计的。
下面就是一个抽象的柯里化函数
var currying = function(fn) { var args = [...arguments].slice(1); return function() { if (arguments.length === 0) { return fn.apply(this, args); // 没传参数时,调用这个函数 } else { [].push.apply(args, arguments); // 传入了参数,把参数保存下来 return arguments.callee; // 返回这个函数的引用 } } }
实际场景的运用能更好的加深我们的理解,所以我们用实际的生活场景来看看 柯里化 如何运用。
场景:记账本,每天记录使用多少钱,一个月算一次总花费(或者在我想要知道的时候)
function account(){ var total = []; function money(p) { if (arguments.length === 0) { // 计算一共花了多少钱 total = total.reduce((sum, value) => { return sum + value; }, 0) console.log('一共花了', total+' 元'); } else { // 记录每天花了多少钱 total.push(p) console.log('今天花了', p+' 元'); } } return money; }
这个我们就定义好了一个 柯里化 的记账本。 我们来用一下
var spend = account(); spend(15) // 今天花了 15 元 spend(30) // 今天花了 30 元 spend() // 一共花了 45 元 (不传参数的时候就返回真正的结果)
Tip:高阶函数:一个函数接收另一个函数作为其参数。
参考:函数式编程与面向对象编程[1]: Lambda表达式 函数柯里化 高阶函数
如果某些参数在大部分情况下,总是需要同时给出,才具有真实的意义,那么应该把这些参数组合成一个组合型参数来处理,而不应该科里化。 如果要定义的多参函数是一个闭合函数,那么它是很可能需要被多次应用的,这种情况下,应该用组合型参数的方式来处理。 如果先指定某一些参数就有明确的意义,那么就应该用科里化的方式来处理。
Cool and easy!
对于函数柯里化之前就了解过,大概知道是个什么东西。 最近在读Vue源码的时候,看到了
cached
函数的使用,让我觉得这个代码写的挺有意思,于是在sf发问,看了@sunyongjian
回答,于是又绕到了柯里化
和高阶函数上
。柯里化定义
维基中有对柯里化的定义:在计算机科学中,柯里化(英语:Currying),又译为
卡瑞化
或加里化
,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。用JavaScript表达定义
着重看 多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数
使用
其实就是逐渐消元的过程。知乎上也有类似的问题,具体见:如何理解functional programming里的currying与partial application
通用的柯里化函数
上面的例子虽然解释了什么是柯里化,但是还不通用,因为 参数个数 理论上是无法估计的。
下面就是一个抽象的柯里化函数
场景使用
实际场景的运用能更好的加深我们的理解,所以我们用实际的生活场景来看看 柯里化 如何运用。
场景:记账本,每天记录使用多少钱,一个月算一次总花费(或者在我想要知道的时候)
这个我们就定义好了一个
柯里化
的记账本。 我们来用一下何时使用柯里化
如果某些参数在大部分情况下,总是需要同时给出,才具有真实的意义,那么应该把这些参数组合成一个组合型参数来处理,而不应该科里化。 如果要定义的多参函数是一个闭合函数,那么它是很可能需要被多次应用的,这种情况下,应该用组合型参数的方式来处理。 如果先指定某一些参数就有明确的意义,那么就应该用科里化的方式来处理。