Curry - Part 5 of 函数式编程
-
Curry (咖喱)函数 只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。如果你不知道我在说什么,没关系,一步一步来:
首先看一个普通函数:function person = (name, height, weight) { return name + '身高' + height + ', 体重' + weight; }
用ES6箭头函数可以简写为:
const person = (name, height, weight) => name + '身高' + height + ', 体重' + weight; console.log(person('Tom', '1米78', '150公斤')); //Tom身高1米78, 体重150公斤
如果你不知道为什么可以这么写,请查看[这里]。(https://j4fun.com/topic/48/map-arrow函数的简写-part-2-of-函数式编程)
接下来,我们把以上函数用咖喱函数来表示:function curryPersonFunction (name) { return function personHeightWeight(height, weight) { return name + '身高' + height + ', 体重' + weight; } }
注意:curryPersonFunction()函数现在只接一个参数name,然后返回一个函数personHeightWeight()。这么一来,我们可以用下面的函数调用来实现上面普通函数需要实现的结果:
const tom = curryPersonFunction('Tom'); //tom 在这里是一个函数 console.log(tom('1米78', '150公斤')); //Tom身高1米78, 体重150公斤
以上的例子或许不能解释为什么要用Curry函数,但是发挥点想象力,你可能注意到,我们可以用Curry函数把一部分函数单独分离出来,这样就可以重复使用它来提高代码的可读性。
比如下面这个例子:
const data = { "user": "adam", "posts": [ { "title": "why curry?", "contents": "curry is cool" }, { "title": "why functional", "contents": "functional is clean" } ] }; function getObjProp(propName, obj){ return obj[propName]; } const titles = getObjProp("posts", data).map(post => { return getObjProp("title", post) }); console.log(titles); //["why curry?","why functional"]
上面例子里,getObjProp是一个普通函数,它接受两个参数,一个是属性名,另外一个是object,然后返回这个属性的值。如果把它写成curry函数,在配上“级联”函数,比如map,我们就不用每次都传入object了。
const get = prop => obj => obj[prop]; const titles = get('posts')(data).map(get('title'));
本章对于codePen:
例子一:Curry基础
例子二:Curry和Map的妙用