compose函数指的是,将需要嵌套执行的函数平铺。而嵌套执行指的是,一个函数的返回值将作为另一个函数的参数。
而compose函数的作用是,实现函数编程中的Pointfree,使我们专注于转换而不是数据。
let add = x => x + 10;
let multiply = y => y*10;
let compose = function(){
let args = [].slice.call(arguments);
return function (x){
return args.reduceRight(function(res,cb){
return cb(res);
},x)
}
}
let calculate = compose(multiply,add);
calculate(10);//值为200
那么这里我们需要先掌握的基础有。
1.slice 用来将 array-like 对象转换为 true array。
2.call()方法
function func(name, price) {
this.name = name;
this.price = price;
}
var food = {name:"apple",price:10};
func.call(food,"orange",15);
console.log(food); // {name: "orange", price: 15}
// 调用call方法传入的参数比原方法多一个参数,简单来说,call方法的作用就是:用call方法的第一个参数代替func方法内部的this,其他参数为原func方法的参数。
我们写一个具体的例子来帮助理解:
var args = [];
var obj = {0:"www",1:"jianshu",2:"com",length:3};
for (var i = 0; i < obj.length; i++) {
args.push(obj[i]);
}
console.log(args); //["www","jianshu","com"]
//等价于以下的写法
console.log([].slice.call(obj)); //["www","jianshu","com"]
reduceRight和reduce其实就是一个是降序,一个是升序。即一个是从数组最后一个开始从前,一个是从数组第一位开始从后。
我们直接拿reduce来说:
array1.reduce(callbackfn,[initialValue])
//array1 必需。一个数组对象。
//callbackfn 必需。一个接受最多四个参数的函数。对于数组中的每个元素,reduce 方法都会调用 callbackfn 函数一次。
//initialValue 可选。如果指定 initialValue,则它将用作初始值来启动累积。第一次调用 callbackfn 函数会将此值作为参数而非数组值提供
//返回值为最后一次调用回调函数callbackfn获得的累计结果
而回调函数callback
function callbackfn(previousValue, currentValue, currentIndex, array1)
//previousValue 通过上一次调用回调函数获得的值。如果向 reduce 方法提供 initialValue,则在首次调用函数时,previousValue 为 initialValue。
//currentValue 当前数组元素的值。
//currentIndex 当前数组元素的数字索引。
//array1 包含该元素的数组对象。
第一次调用回调函数
在第一次调用回调函数时,作为参数提供的值取决于 reduce 方法是否具有 initialValue 参数。
如果 reduce 方法提供 initialValue:
previousValue 参数为 initialValue。
currentValue 参数是数组中的第一个元素的值。
如果未提供 initialValue:
previousValue 参数是数组中的第一个元素的值。
currentValue 参数是数组中的第二个元素的值。
上述reduceRight理解部分来自于CSDN博主「Simon_ITer」的原创文章
原文链接:https://blog.csdn.net/simoniter/article/details/52013660
我们再次结合我们的compose函数
let add = x => x + 10;
let multiply = y => y*10;
let compose = function(){
let args = [].slice.call(arguments);
//arguments是function没有定义却实际传入的参数[ps:add和multiply方法]
//上述代码将arguments转换为数组使用
console.log(args);//[y => y*10,x => x + 10]
return function (x){
//x为传入的参数10
return args.reduceRight(function(res,cb){
// res为上一次调用回调函数获得的值,初始化为下面的x,即首次传入的10
// cb当前数组元素的值,即函数add或multiply
return cb(res);
},x)
//这里的x作为reduceRight首次调用时的初始值调用,供res使用
}
}
let calculate = compose(multiply,add);
calculate(10);
最终的值200便是我们所要得出的值。