高阶函数
高阶函数是把函数当参数或者当返回值都是高阶函数。
纯函数
纯函数就是不改变原数据的函数。
例如数组的方法有slice返回一个新数组、splice则是对原数是有影响的。所以slice是纯函数,而splice不是纯函数。
柯理化函数
概念
柯里化函数是一个高阶函数,柯里化函数就是多个参数时,当有一个参数是固定的,其他参数是变动的。那么可以生成一个柯里化函数,固定参数不变,而变动的参数不同生成不同的效果。
实现一个柯里化函数
函数的参数长度是可以直接获取的。
function aa(a,b,c){}
console.log(aa.length); //直接可以获取函数参数的长度
具体实现的过程和详细说明:
function _sum(a,b,c){
console.log("被执行");
return a+b+c;
}
//如果我们输入三个参数则可以直接返回三个参数的和
console.log(_sum(1,2,3)); //6
//不过我们在实际的开发业务当中,参数是不太可能一次性获取的,需要多次进行获取,所以使用柯里化函数来实现
//这个函数是生成一个柯里化函数
function kelihua(fun){//传入一个函数,最终这个函数变成一个柯里化函数
return function _kelihua(...args){//这个是返回的柯里化函数
if(args.length>=fun.length){//如果传入的实参大于本身函数的形参,那么说明参数已够,直接执行就可以
return fun(...args);//直接执行这个方法
}else{
//如果参数不够,那么就要继续返回函数就接收新传入的参数,直到多个参数相加后大于函数的形参
return function (){
console.log("打印当前参数:::>>>",args.concat(Array.from(arguments)));
return _kelihua(...args.concat(Array.from(arguments)));//arguments是一个类数组,不是真的数组
}
}
}
}
//测试柯里化函数,第一步生成柯里化函数
let klh=kelihua(_sum);
console.log(klh(1,2,3));//6
console.log(klh(1,2)(3));//6
console.log(klh(1)(2,3))//6
函数组合
函数组合是把多个函数组合到一个函数里边。
正常我们执行对个函数的形式是:
fn1(fn2(fn3())) 则三个函数按照顺序执行时 fn3执行完毕 才执行 fn2 fn2执行完毕才执行fn1 这个是典型的洋葱模型,不利于阅读。
函数组合的基本实现
将多个函数作为参数组合成一个函数,如下:
let fn=compose(fn1,fn2,fn3)
fn(内容1) //则fn就是执行fn1 把fn1执行的结果给fn2 以此类推
fn(内容2)
...
这样fn可以重复使用。同时通过函数参数不同,可以生成不同的函数组合
例如 const newFn=compose(fn3,fn4); //又组成了一个新的函数组合
代码实现一个函数组合
传统方法
我们首先看一下传统的方法实现:
let _str="hello huang fei hou";
/*
需求:变成大写,同时用- 链接起来 并且是反向的
所以第一步:变成数组 用空格切割变成数组,然后反向
第二步:然后再连接成字符串
第三步变成大小
*/
//普通的方法,洋葱模型
//第一步:切割方法
function fn1(data){
return data.split(" ");
}
//第二个方法,是反转数组
function fn2(data){
return data.reverse();
}
//fn3在链接成字符串
function fn3(data){
return data.join(" ");
}
//fn4是把小写变成大写
function fn4(data){
return data.toUpperCase();
}
console.log(fn4(fn3(fn2(fn1(_str)))));//HOU FEI HUANG HELLO
\
这个方法在于,每次我都要调用这种洋葱模式的嵌套方式,如果有100个方法就要嵌套100次,并且不利于管理、阅读麻烦。
函数组合方法
把多个函数组合成一个函数的方法,以及这个方法执行的结果:
let _str="hello huang fei hou";
/*
需求:变成大写,同时用- 链接起来 并且是反向的
所以第一步:变成数组 用空格切割变成数组,然后反向
第二步:然后再连接成字符串
第三步变成大小
*/
//普通的方法,洋葱模型
//第一步:切割方法
function fn1(data){
return data.split(" ");
}
//第二个方法,是反转数组
function fn2(data){
return data.reverse();
}
//fn3在链接成字符串
function fn3(data){
return data.join(" ");
}
//fn4是把小写变成大写
function fn4(data){
return data.toUpperCase();
}
console.log(fn4(fn3(fn2(fn1(_str)))));//HOU FEI HUANG HELLO
//打印方法,每次执行函数结束后打印当前执行的结果
function log(data){
console.log(data);
return data;
}
//函数组合的方法
function compose(...args){
return function(value){//传进来需要被执行的内容
return args.reduce((prevValue,next)=>{//prev是上一次执行的结果、next是当前数组的值
return next(prevValue);
},value);
}
}
let _compose=compose(fn1,log,fn2,log,fn3,log,fn4,log);
console.log(_compose(_str)); //HOU FEI HUANG HELLO