js 柯里化艺术

293 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情

前言

在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。这个技术由 Christopher Strachey 以逻辑学家 Haskell Curry 命名的,尽管它是 Moses Schnfinkel 和 Gottlob Frege 发明的。

js 柯里化

在js里,柯里化也是一样的道理

  • 当一个函数有多个参数的时候先传入一部分参数调用它(这部分参数以后永远不会变)
  • 然后返回一个新的函数接收剩余的参数,返回结果

手写代码实现柯里化

最简单的柯里化实现理解:

/**
 * 普通函数
 */
function compareAge(min, age) {
  return age >= min
}
console.log(compareAge(18, 20)) // true
console.log(compareAge(18, 16)) // false
console.log(compareAge(18, 32)) // true

如果经常使用参数18的话,就可使用柯里化将最小参数提取

/**
 * 柯里化实现
 */
function compareAge(min) {
  return function (age) {
    return age >= min
  }
}
const compareAge18 = compareAge(18)

console.log(compareAge18(20)) // true
console.log(compareAge18(16)) // false
console.log(compareAge18(32)) // true

进阶艺术:

面试常考题,让你实现相加 add(1)(2)(3),或者变形 add(1)(2,3)
这时就会用到柯里化的思想:

// 求和函数
function getSum(a,b,c){
  return a + b + c
}

// 柯里化函数
function curry(func){
  // 获取一部分参数返回,如果参数不够,继续返回自己并且拼接上参数
  return function curriedFn(...args){
    // 判断实参和形式参数额个数
    if(args.length < func.length){
      return function(){
        return curriedFn(...args.concat(Array.from(arguments)))
      }
    }
    return func(...args)
  }
}

// 柯里化
let curried = curry(getSum)

console.log(curried(1,2,3)) // 6
console.log(curried(1)(2)(3)) // 6
console.log(curried(1,2)(3)) // 6

如果是任意多个相加 add(1)(2)(3,4)(5)(6),可简写为:

function add(...args) {
  // 注意6为add后面参数的个数
  if (args.length < 6) {
    return function(){
      return add(...args, ...arguments)
    }
  }
  return args.reduce((sum, cur) => sum + cur, 0)
}

console.log(add(1)(2)(3,4)(5)(6)) // 21

柯里化总结

  1. 柯里化可以让我们给一个函数传递较少的参数得到一个已经记住了某些固定参数的新函数
  2. 这是一种对函数参数的缓存
  3. 让函数变得更灵活,让函数的粒度变得更小
  4. 可以把多元函数转换成一元函数,可以组合函数产生强大的功能

往期精彩文章

🌟简述BFC是什么,以及在工作中的应用场景
🌟从浏览器输入网址到页面渲染中间发生了什么(通俗易懂)
🌟发布订阅/观察者模式-真正对比区别
🌟webpack 手写插件流程
🌟两种方式轻松做react css样式隔离