005 currying 柯里化函数的实现

8/4/2022 JS API

# 1. 函数作用


调用柯里化函数,并传递一个想转换成柯里化函数的函数,得到一个新函数,可对该新函数进行柯里化的调用得到最终结果

# 2. 总体步骤


  1. 柯里化函数最终会返回一个函数,所以,先定义一个 curried 函数,最后再返回
  2. 在 curried 函数里面先进行参数个数的判断

# 3. 详细步骤


  1. 柯里化函数最终会返回一个函数,所以,先定义一个 curried 函数,最后再返回

  2. 在 curried 函数里面先进行参数个数的判断

    • 参数已满时,直接用 apply 方法调用传入的函数并返回
    • 参数未满时,直接返回一个定义的函数,在里面递归使用 apply 方法 调用 curried 函数并返回

# 4. 代码实现


/**
 * * 柯里化函数实现
 * @param {Funcion} fn 想转换成柯里化的函数
 * @returns 
 */
function binCurrying(fn) {
  function curried(...args) {
    if (args.length >= fn.length) {
      return fn.apply(this, args)	// 参数已满时
    } else {
      return function (...args2) {   
        return curried.apply(this, [...args, ...args2])	// 参数未满时
      }
    }
  }
  return curried
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 5. 测试代码


// 测试代码
function add1(x, y, z) {
  return x + y + z
}

// 调用 binCurrying 函数,得到柯里化函数
let curryAdd = binCurrying(add1)  

console.log(curryAdd(10, 20, 30)) // 60
console.log(curryAdd(10, 20)(30)) // 60
console.log(curryAdd(10)(20)(30)) // 60
1
2
3
4
5
6
7
8
9
10
11

# 6. 细节解析


  1. 返回的 curried 函数参数必须用展开运算符展开,因为不确定会传入几个参数
  2. fn.length 得到的是 fn 函数参数的长度(个数)
  3. 调用 fn 函数是要使用 apply 方法调用,并且将 this 改为正确的指向,因为不清楚得到柯里化函数后,是由什么方式调用的
  4. 在参数未满时返回的函数中,接收的参数也要用展开运算符展开
  5. 在递归使用 apply 方法调用 curried 函数时,第二个参数要将上一次的参数与这一次的参数进行拼接成为一个数组

# 7. 核心原理


​ 进行参数是否满足的判断,如果不满足,就要递归使用 apply 方法调用 curried 函数,第二个参数要将上一次的参数与这一次的参数进行拼接成为一个数组进行传递。通过不断地递归调用,等到满足条件时,所有的参数就会组成一个数组进行调用得到结果并返回

Last Updated: 1/28/2022, 1:21:13 PM