前言

  1. 柯里化就是把接收多个参数的函数转化成接收单一参数的函数,并且返回一个(可以接收剩余参数的)新函数。
  2. 优点:可以延迟计算,也就是调用柯里化函数时传入的参数不是立即调用的,而是只有当满足一定条件时
  3. 才会(将已经在数组中存储的参数作为参数)执行;参数可以复用,当多次调用同一个函数,并且传递的
  4. 参数绝大多数是相同的,那么该函数可能是一个很好的柯里化函数。

实现

1.lodash中的curry方法就是一个柯里化函数 https://www.lodashjs.com/docs/lodash.curry
2.自己实现一个通用的柯里化函数

  1. function sum(a,b,c,d) {
  2. return a + b + c + d;
  3. }
  4. const curring = (fn:Function) => {
  5. const exec = (sumArgs:any[] = []) => {
  6. return sumArgs.length >= fn.length ? fn(...sumArgs)
  7. : (...args) => exec([...sumArgs,...args])
  8. }
  9. return exec() //exec()的参数可以是初始化的值,可以是重复传递的参数
  10. }
  11. let test = curring(sum)(......)
  12. //"......"指的是传递给sum函数的参数,形式有两种,如1.(1,2,3,4) 2. (1,2)(3)(4)......

场景

减少重复不变的参数

实现url的拼接,如果我们要拼接一个url,即协议+域名+路径,那么重复参数的情况便出现,如协议是http还是https?如下

  1. function splicingUrl(protocol,domain,path){
  2. return `${protocol}://${domain}/${path}`
  3. }
  4. splicingUrl(http,www.baidu.com,home)
  5. splicingUrl(https,taobao.com,datail)

下面通过柯里化实现减少传递重复参数的功能

  1. function splicingUrl(protocol,domain,path){
  2. return `${protocol}://${domain}/${path}`
  3. }
  4. const curryPackage = (fn:Function) => {
  5. const curryFunc = (splicingArgs:any[] = []) => {
  6. return splicingArgs.length >= fn.length ? fn(...splicingArgs)
  7. : (...args) => curryFunc([...splicingArgs,...args])
  8. }
  9. return curryFunc()
  10. }
  11. let newCurry = curryPackage(splicingUrl)('http','www.baiducom')
  12. newCurry('home.html') //http://www.baiducom/home.html
  13. newCurry('photo.html') //http://www.baiducom/photo.html

将柯里化之后的callback参数传递给map/filter等函数

  1. let studentsInfo = [{name:'tom',age:19},{name:'jarry',age:32},{name:'susan',age:33}]
  2. function getObj(key,obj){
  3. return obj[key]
  4. }
  5. //将callback进行柯里化
  6. import _ from 'lodash';
  7. let curryCallback = _curry(getObj)
  8. let nameArray = studentsInfo.map(curryCallback('name')); // ['tom','jarry','susan']
  9. let agesArray = studentsInfo.map(curryCallback('age')); // [19,32,33]