柯理化是一种关于函数的高阶技术。
柯里化是一种函数的转换,它是指将一个函数从可调用的 f(a, b, c) 转换为可调用的 f(a)(b)(c)。
柯里化不会调用函数。它只是对函数进行转换。
一个最简单的例子javascript
// 本来的sum函数以及应用 function sum(a, b) { return a + b; } sum(1,2) // 3 // 柯理化后的sum函数以及应用 function curry_sum(a) { return function(b){ return a+b } } sum(1)(2) // 3 // 或者 fn=sum(1) fn(2) ==>3
柯理化的使用确定不是为了装逼,或者说不单单为了装逼。java
柯理化能够延迟执行,达到参数复用的目的。(我的理解动态函数和惰性函数和柯理化没啥关系)node
原先是sum(1,2)当即执行,如今能够先fn=sum(1) 而后再fn(2) 这个就对于函数的执行可控了git
第一次传参并不执行,咱们先埋伏它一波。github
后面函数执行的时候复用的咱们第一次传的参,这个就叫延迟执行,参数复用。这样能够大幅度简化咱们的代码。ajax
虽然咱们能够根据柯理化的思想,写出咱们想要的函数,好比以前的curry_sum
segmentfault
可是咱们最好能写个更通用的柯理化函数,它接受一个fn,返回一个包装后的函数curry_fn,完成咱们所须要的参数复用和延迟执行功能。api
这里参考Lodash咱们看一个curry函数长啥样闭包
/** * 参数 * func: 用来柯里化(curry)的函数。 * [arity=func.length] : 须要提供给 func 的参数数量。 * * 返回 * (Function): 返回新的柯里化(curry)函数。 */ function curry(func, [arity=func.length]){ }
咱们给出它的测试用例app
// curry.test.js const{curry} = require('./index') test('curry',()=>{ const add = (a,b,c)=>{ return a+b+c } const sayhi = function(){ return this.name } const curry_add = curry(add) const curry_sayhi = curry(sayhi) const obj = {name:'fyy'} expect(curry_sayhi.call(obj)).toBe('fyy') expect(curry_add(2)(3)(4)).toBe(9) expect(curry_add(1)(2,3)).toBe(6) expect(curry_add(1,2)(2)).toBe(5) expect(curry_add(1,2,1)).toBe(4) })
咱们在index.js里面实现一个curry函数
实现的时候须要注意几个关键点
//index.js const curry = function(fn){ return function curried(...args){ //这里不能用箭头函数 if(fn.length===args.length){ return fn.apply(this,args) }else{ return function(...args1){ return curried.apply(this,args.concat(args1)) } } } } module.exports = { curry }
咱们跑一下测试用例,证实函数没有问题。
看两个柯理化的例子,加深一下理解
好比api长这样 ajax(method,url,params)
// 咱们能够在serve.js里封装一个post const post = url=> data => ajax('post',url,params) // 在module1api.js里面封装一些地址 import {post} from 'serve.js' const getList = post('www.xxx.com/api/xxx') // 在须要调接口的地方,咱们只用传递参数就好了,调用方式和地址已经提早穿过了 // 第一处地方 import{getList} from 'module1api.js' const data = getList(params) // 第二处地方 import{getList} from 'module1api.js' const data = getList(params) // 第N处地方... import{getList} from 'module1api.js' const data = getList(params)
拿到后台的数据 常常要处理
好比原始数据 const data = [{name: 'kevin'}, {name: 'daisy'}]
咱们须要处理成['kevin','daisy']
每次在这都调用Map方法实际上代码很臃肿
var _data = data.map(function (item) { return item.name; })
咱们其实能够这么写,这也是利用了柯理化
const prop = curry(function (key, obj) { return obj[key] }); var _data = person.map(val=>prop('name')(val)) // var _data = person.map(prop('name')) /* *若是想直接这么调的话,curry须要改一下, 把fn.length===args.length中的===改成>== 你们能够好好想想缘由, */
柯理化其实挺经常使用的,不必定非要用curry函数,理解它的思想咱们就能写出很优美很高效的代码。
总归就是闭包的一种应用。
柯理化
JavaScript专题之函数柯里化
lodash_curry
深刻高阶函数应用之柯里化
https://segmentfault.com/a/1190000018180159