JS高阶函数:柯里化函数
柯里化函数
柯里化函数简单来说就是用于创建已经设置好了一个或多个参数的函数。在基本用法上和函数绑定是一样的:使用一个闭包返回一个函数。两者的区别在于,当函数被调用时,返回的函数还需要一些传入的参数;
- 示例
function add(x,y) {
return x+y
}
function curryingAdd(y) {
return add(5,y)
}
console.log(add(2,3)) //5
console.log(curryingAdd(3)) //8
- 这段代码定义了两个函数:add()和curryingAdd()。不同的时,curryAdd是第一个参数为5的add()版本,从技术角度来说curryingAdd()并不是柯里化函数,但是却很好的展示了其概念。
柯里化函数的创建
- 调用另一个函数并为它传入要柯里化的函数和必要参数,下面是创建柯里化函数的通用方式。
function curry(fn) {
let args = [].slice.call(arguments,1);
retunr function () {
let innerArgs = [].slice.call(arguments),
arr = args.concat(innerArgs);
return fn.apply(null,arr);
}
}
curry函数的第一个参数就是要进行柯里化的函数,其它参数是传给要柯里化函数的参数,可以用数组原型上的slice方法把arguments截取并转换为数组,即args数组包含了外部函数的参数。在内部函同样使用slice方法,将内部函数的参数存放到innerArgs中,然后利用数组拼接把所有参数合并在一个存放在arr数组中,使用apply()将结果传递给要柯里化的函数;
function add(x,y){
return num1+num2;
};
let curryingAdd = curry(add,5);
console.log(curryingAdd(3)); //8
这个例子中,add函数就是要进行柯里化的函数;柯里化的过程中,把第一个参数绑定为5,,当调用curryingAdd()的时候,传入3,3会成为add()的第二个参数,即x=5,y=3,结果就是8。
柯里化函数的经典应用:模拟内置bind()函数
Function.prototype.myBind = function myBind(context) {
//确保传入的参数不是null或者undefined
context == null ? context = window : null;
// 判断传入的参数是否为引用数据类型,如果不是改为引用数据类型
if (typeof context !== 'object' || typeof context !== 'function') {
context = new context.constructor(context);
};
let args = [].slice.call(arguments, 1),
that = this;
return function () {
let innerArgs = [].slice.call(arguments),
arr = args.concat(innerArgs);
return that.apply(context, arr);
}
};
function func() {
console.log(this,arguments);
};
let obj = {
name: 111,
}
document.body.onclick = func.myBind(obj, 100, 200) //=>{name: 111}; [100, 200, MouseEvent, callee: ƒ, Symbol(Symbol.iterator): ƒ]
myBind()与js内置的bind()方法基本一致,只要在this的值之后传入另一个参数即可。
结尾
js中的柯里化函数能创建复杂的算法和功能,虽然柯里化函数比较强大,但是使用的时候应该慎重,因为每个函数都会带来额外的性能消耗。