js15-函数柯里化

207 阅读2分钟

函数柯里化

柯里化(Currying),又译为卡瑞化或加里化,是把接受多个参数的函数变换成接受一个单一参 数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。

找找感觉

下面有计算两个数之后的两种写法,

// 普通函数
function add(x, y) {
 return x + y; 
}
// 函数调用
add(1, 2) // 3

暗藏柯里化思想的写法

// 柯里化之后
function addX(y) {
     return function (x) {
	return x + y;
     }; 
}
addX(2)(1) // 3

当然,上面的代码并不具备通用性,下面看一个更复杂的例子。

手写一个柯里化函数

目标: 把下面的代码补全,并能通过如下的测试用例。

function curry () {
   // 你的代码
}
function sum(a, b, c) {
    console.log(a + b + c);
}
 
const fn = curry(sum);
// 测试用例
fn(1, 2, 3); // 6
fn(1, 2)(3); // 6
fn(1)(2, 3); // 6
fn(1)(2)(3); // 6

柯里化的通用实现

最核心的思路:

  1. 接收一部分参数,返回一个函数接收剩余参数
  2. 接收足够参数后,执行原函数

背景知识:通过函数的 length 属性,可获取函数的形参个数

参考答案

// func 要做柯里化处理的函数; 
// curArg 用来统一接收实参的数组,这里用到了默认值,并构成一个闭包结构
function curry (func,curArg=[]) { 
   return  function (...arg) {
       arg = curArg.concat(arg)
       if(arg.length >= func.length) { // 收到的参数个数够了没有
           return func.apply(null,arg)
       } else {
           return  curry(func,arg)
       }
   }
}

柯里化的取舍

  1. 柯里化把事情搞复杂了。对于函数fn,本来可以直接传入所有的值进行求解,而经过柯里化之后,要逐步传入参数,逐步求解。
  2. 柯里化把让函数更加灵活。 举个判断数据类型的例子来验证下
// 定义函数
function checkType(type,value) { 
    return Object.prototype.toString.call(value) === `[object ${type}]`; 
}
// 测试功能
console.log(checkType('Array',[])) // true

从这个函数出发,可以用柯里化得到更多的功能函数

const isArray = curry(checkType,['Array']) // 从checkType得到了新函数isArray
const isFucntion = curry(checkType,['Function'])
// 测试使用
isArray([])
isFucntion(()=>{})