柯里化就是函数和参数相结合形成新的函数,其主要用处在于:
对于一个函数,如果在程序中我们需要多次调用,并且参数都相同(或者部分相同),例如Array的sort函数,我们就可以考虑将函数柯里化(curry),减少代码量。
如何实现
柯里化的原理主要是要返回一个函数,这个函数中有来自闭包的变量记录了创建时的默认参数,然后执行这个返回函数时,把新传入的参数和默认参数拼合成完整参数去调用原来的函数
先贴出代码
Function.prototype.curry=function(){
let slice=Array.prototype.slice;
//通过slice将类数组对象变为数组对象
let defaultArgu=slice.call(arguments);
//this表示curry函数的调用环境(一般是需要柯里化的函数对象)
let that=this;
//返回一个新的函数
return function(){
//that表示原先的函数对象,defaultArgu表示默认参数,此时的arguments是调用时的参数
return that.apply(this,defaultArgu.cancat(slice.call(arguments)))
}
}
举例说明
1、一个普通函数add,调用时参数a都一样都为5
function add(a,b){
return a+b
}
add(5,1);
add(5,3);
将其柯里化
function add(a,b){
return a+b
}
let add1=add.curry(5);
add1(1);
add1(3);
我们来分析柯里化的过程都发生了什么,将参数5代入curry函数
Function.prototype.curry=function(){
let slice=Array.prototype.slice;
//defaultArgu=[5]
let defaultArgu=slice.call(arguments);
//通过add调用curry,that=this=add
let that=this;
return function(){
//相当于
//return add.apply(this,[5].concat([1]))
//return add(5,1)
return that.apply(this,defaultArgu.cancat(slice.call(arguments)))
}
};
而add1函数最终变为
var add1=function(b){
return add(5,b)
}
2、sort函数,需要正序排序,参数固定为(a,b)=>a-b
Array.prototype.sortByOrder=Array.prototype.sort.curry((a,b)=>a-b);
let arr=[4,2,1,5,6];
arr.sortByOrder();
柯里化过程
Function.prototype.curry=function(){
let slice=Array.prototype.slice;
//defaultArgu=[(a,b)=>a-b]
let defaultArgu=slice.call(arguments);
//通过sort调用curry,that=this=sort
let that=this;
return function(){
//相当于
//return sort.apply(this,[(a,b)=>a-b].concat([]))
//return sort((a,b)=>a-b)
return that.apply(this,defaultArgu.cancat(slice.call(arguments)))
}
};
最终的函数为
Array.prototype.sortByOrder=function(){
return Array.prototype.sort.call(this,(a,b)=>a-b)
}