js函数柯里化(curry)和函数合成(compose)

2020-9-6 21:23:31
学习记录
159

函数柯里化(curry) 和 函数合成 (compose)

函数柯里化

函数柯里化指的是把一个需要多个参数的函数,改写成只需要一个参数的函数。

函数柯里化的关键在于 熟悉函数的 call apply 的使用,对函数 arguments 对象的理解。

使用柯里化的例子

//假设有一个柯里化函数 curry function curry(){ //code... } //需要一个求和的运算函数 function add(){ return [].slice.call(arguments).reduce((accumulator,currentValue)=>{ return typeof currentValue === 'number' && typeof accumulator === 'number' ? accumulator + currentValue : accumulator; }) } //未柯里化时候调用方式 console.log(add(1,2,3));//输出6 //柯里化后调用 const addcurry = curry(add); console.log(addcurry(1)(2)(3)())//输出6

函数柯里化具体实现

const curry = function(fn){ let orangeLen = fn.length;//缓存原始函数中所需要的参数个数 let args = [].slice.call(arguments,1)//缓存获取传入的除了原始函数函数之外的其他参数。 return function(){ args = [...args,...arguments];//把原来传递的参数和现在函数中参数合并 //如果原始函数没有形参并且当前调用的函数中没有传参,触发了执行条件; //如果原始函数有形参并且累计调用函数的参数超过或者等于原始函数形参数量,触发执行条件 if( (orangeLen ==0 && arguments.length ==0 ) || ( orangeLen > 0 && args.length >= orangeLen ) ){ return fn.apply(this,args); } return arguments.callee; } }

有形参的函数柯里化使用

var add = function (a,b,c) { //求和函数,3个参数之和 return a + b + c; } //柯里化函数 var curried = curry(add, 2); console.log(curried(1) (2)); //5 var curried = curry(add, 2, 1); console.log(curried(2)); //5 var curried = curry(add); console.log(curried (1) (2) (6)); //9 var curried = curry(add); console.log(curried(1,2,6)); //9

无形参的函数柯里化使用

//求和函数,参数不限 var add = function () { //迭代所有参数值,返回最后汇总的值 return [].slice.call(arguments).reduce(function (a,b) { //如果元素的值为数值,则参与求和运算,否则设置为0,跳过非数字的值 return (typeof a == "number" ? a : 0) + (typeof b =="number" ? b : 0); }) } //柯里化函数 var curried = curry(add); console.log(curried(1) (2) (3) ()); //6 var curried = curry(add); console.log(curried(1,2,3) (4) ()); //10 var curried = curry(add, 1); console.log(curried(1,2) (3) (3) ()); //10 var curried = curry(add, 1, 5); console.log(curried(1,2,3,4) (5) ()); //21

函数合成

函数合成指的是把多个函数嵌套调用,合并成为一个函数,并传递初始参数调用。

语法

//循环调用的函数 a(b(c(x))); var f = compose(a, b, c); //合成函数 f(x);

函数合并(compose)的要求

  • compose 函数的参数必须是函数类型的,可以接收任意个参数,执行方向从右向左
  • 除了初始函数(最右侧的一个)外,其他函数的接收参数都是一个函数的返回值,所以初始函数的参数可以是多元的,而其他函数的接收值是一元的。
  • 初始函数一定要放在最右侧

函数合并的具体实现

function compose(){ const _args = arguments; const length = arguments.length; let index = length ; while(index--){ if( typeof _args[index] !== 'function' ){ throw new Error('参数必须是函数') } } return function (){ let index = length-1;//真实参数 //compose的函数类型的参数如果存在,则调用最后一个参数,否则,直接返回第 1 个参数函数 let result = length ? _args[index].apply(this,arguments) : arguments[0]; while(index--){ result = _args[index].call(this,result); } return result; } }

使用例子🌰

var add = function (x) { return x + 5; } //加法允许 var mul= function (x) { return x * 5; } //乘法运算 var sub= function (x) { return x - 5; } //减法运算 var div = function (x) { return x / 5; } //除法运算 var fn = compose(add, mul, sub, div); console.log(fn(50)); //返回30 var fn = compose(add, compose(mul, sub, div)); console.log(fn(50)); //返回30 var fn = compose(compose(add, mul), sub, div); console.log(fn(50)); //返回30

js函数柯里化(curry)和函数合成(compose)

avatar

Sky(小新)

个人签名: 提升能力,创造价值!

江苏-南京
skylpz@qq.com