小二,上酒!
天涯的渡口, 一人陪马儿清瘦, 多么富有, 天下了心中。
compose函数
当一个函数的参数是另一个函数的执行结果的时候,可以使用compose函数 例如:
function add(num){
return num + num;
}
function multiply(num){
return num * num;
}
//有以上两个函数,如果我们想先执行add函数,再用add函数的执行结果去执行multiply函数
//我们可能会这样做
const addRes = add(10);
const mRes = multiply(addRes);
//或者这样
const res = multiply(add(10));
console.log(res) //400
compose的写法:
function compose(){
//拿到参数数组
const args = [].slice.call(arguments);
return function (num){
//利用数组的reduce方法,每个cb就是传进来的方法
//res是方法的执行结果,第一次循环res是传递进来的num 也就是10
return args.reduce((res,cb)=>{
return cb(res)
},num)
}
}
const res = compose(add,multiply)(10)
console.log(res) //400
compose的好处是:
当你理解它的执行流程时,看起来代码更简洁、清晰、方便阅读。我们只需要把函数传递给compose,其余的交给compose来做就好。
想一想如果要执行的函数更多的时候:
//普通写法可能是:
const res = d(c(b(a(10))))
//compose的写法是:
const res = compose(a,b,c,d)(10);
curry函数 又叫函数科里化
//当有一个add函数:
const add = (a,b,c,d) => {//为了方便阅读就不写成一行了
return a + b + c + d;
}
//普通调用
const res = add(1,2,3,4);
curry调用的写法:
function curry(fn,...args){
const len = fn.length; //fn.length 是函数的参数个数
const argsArr = [...args];//新建一个数组来保存参数
return function insideFn(...args){
argsArr.push(...args) //再次调用继续保存参数
if(argsArr.length >= len){ //参数收集够了直接执行函数返回结果
return fn(...argsArr);
}else{ //否则继续返回函数
return insideFn;
}
}
}
//调用:
//这样
const res = curry(add)(1,2,3,4);
//或者这样
const res = curry(add)(1)(2)(3)(4);
这时候你可能一脑袋问号?????? 这写法有什么卵用吗? 我直接调用不香吗?
说一说curry的好处:
//我们可以这样使用curry
const curryFn = curry(add,1,2);
const res = curryFn(3,4);
const res1 = curryFn(4,5);
//以后每次调用都不用再传前2个参数
上面curry示例就把参数1和2缓存起来了,试想一下如果参数不是普通类型而是对象或者数组,并且你又对它做了一些处理,那这样只在调用curry的时候处理一次就好,而后续每次再调用curryFn都不会再去处理一遍了。
最后
上面所有的代码都没有做类型判断,如typeof === 'function',理解和会用就好,实际使用可以自己加一下,我就偷个懒,哈哈~
做人和写代码我都不太喜欢复杂的东西,总想着能不能简单点。