前言
柯里化就是把接收多个参数的函数转化成接收单一参数的函数,并且返回一个(可以接收剩余参数的)新函数。
优点:可以延迟计算,也就是调用柯里化函数时传入的参数不是立即调用的,而是只有当满足一定条件时
才会(将已经在数组中存储的参数作为参数)执行;参数可以复用,当多次调用同一个函数,并且传递的
参数绝大多数是相同的,那么该函数可能是一个很好的柯里化函数。
实现
1.lodash中的curry方法就是一个柯里化函数 www.lodashjs.com/docs/lodash…
2.自己实现一个通用的柯里化函数
function sum(a,b,c,d) {
return a + b + c + d;
}
const curring = (fn:Function) => {
const exec = (sumArgs:any[] = []) => {
return sumArgs.length >= fn.length ? fn(...sumArgs)
: (...args) => exec([...sumArgs,...args])
}
return exec() //exec()的参数可以是初始化的值,可以是重复传递的参数
}
let test = curring(sum)(......)
//"......"指的是传递给sum函数的参数,形式有两种,如1.(1,2,3,4) 2. (1,2)(3)(4)......
场景
减少重复不变的参数
实现url的拼接,如果我们要拼接一个url,即协议+域名+路径,那么重复参数的情况便出现,如协议是http还是https?如下
function splicingUrl(protocol,domain,path){
return `${protocol}://${domain}/${path}`
}
splicingUrl(http,www.baidu.com,home)
splicingUrl(https,taobao.com,datail)
下面通过柯里化实现减少传递重复参数的功能
function splicingUrl(protocol,domain,path){
return `${protocol}://${domain}/${path}`
}
const curryPackage = (fn:Function) => {
const curryFunc = (splicingArgs:any[] = []) => {
return splicingArgs.length >= fn.length ? fn(...splicingArgs)
: (...args) => curryFunc([...splicingArgs,...args])
}
return curryFunc()
}
let newCurry = curryPackage(splicingUrl)('http','www.baiducom')
newCurry('home.html') //http://www.baiducom/home.html
newCurry('photo.html') //http://www.baiducom/photo.html
将柯里化之后的callback参数传递给map/filter等函数
let studentsInfo = [{name:'tom',age:19},{name:'jarry',age:32},{name:'susan',age:33}]
function getObj(key,obj){
return obj[key]
}
//将callback进行柯里化
import _ from 'lodash';
let curryCallback = _curry(getObj)
let nameArray = studentsInfo.map(curryCallback('name')); // ['tom','jarry','susan']
let agesArray = studentsInfo.map(curryCallback('age')); // [19,32,33]