js的柯里化(Currying)

180 阅读1分钟

js的柯里化(Currying)

柯里化是什么?

柯里化: Currying 又称为 卡瑞化或加里化
维基百科: 接收多个参数的函数,变成接受一个单一参数的函数

把add()转为jia()的过程称为 柯里化

function add(x, y, z) {
  return x + y + z
}
var result = add(1, 2, 3)
console.log(result)

function jia(x) {
  return function(y) {
    return function(z) {
      return x + y + z
    }
  }
}

var res = jia(10)(20)(30)
console.log(res) // 60

柯里化的单一职责原则

function foo(x, y, z,) {
  x = x + 2
  y = y * 2
  z = z * z
  return x + y + z
}
console.log(foo(1, 2, 3))

// 对参数进行各自的操作
function add(x) {
  // 对x的其他操作
  x = x * 2
  return function(y) {
    // 对y的其他操作
    y = y + 2
    return function(z) {
      // 对z的其他操作
      z = z * z
      return function() {
        return x + y + z
      }
    }
  }
}

console.log(add(1)(2)(3)())

柯里化的优化

function sum(n, m) {
  return n + m
}

// 柯里化的优化一
function adder(n) {
  return function(m){
    return n+m
  }
}
const add5 = adder(5)
console.log(add5(15))

// 柯里化的优化二 (箭头函数)
var add = n => m => {
  return n + m
}
var myadd = add(3)(6)
console.log(myadd)

柯里化函数的实现

// 实现柯里化函数FhCurrying
function add(x, y, z) {
  return x + y + z
}
function FhCurrying(fn){
  return function(...args) {
    // 判断当前函数的参数与本身函数的参数是否一致
    // console.log(args.length) // 返回的函数参数个数
    // console.log(fn.length) // 本身函数参数的个数
    if (args.length >= fn.length) { // 直接调用 curryadd(1,2,3)
      // fn(...args)
      return fn.apply(this, args) // 相当于调用 add(1,2,3)
    } else {
      // 柯里化调用 curryadd(1)(2)(3)
      return function (...args2) {
        return FhCurrying(fn).apply(this,[...args, ...args2])
        // return curried.apply(this, [...args, ...args2])
      }
    }
  }
}

var curryadd = FhCurrying(add)

// 独立函数调用,this = window
console.log(curryadd(10)(20)(30))
console.log(curryadd(10,20)(30))
console.log(curryadd(10,20,30))