前言
柯里化就是把接收多个参数的函数转化成接收单一参数的函数,并且返回一个(可以接收剩余参数的)新函数。优点:可以延迟计算,也就是调用柯里化函数时传入的参数不是立即调用的,而是只有当满足一定条件时才会(将已经在数组中存储的参数作为参数)执行;参数可以复用,当多次调用同一个函数,并且传递的参数绝大多数是相同的,那么该函数可能是一个很好的柯里化函数。
实现
1.lodash中的curry方法就是一个柯里化函数 https://www.lodashjs.com/docs/lodash.curry
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.htmlnewCurry('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]
