js函数柯里化

函数柯里化定义

柯里化就是将多个参数的一个函数转换为使用部分参数传参的多个函数。感觉有点绕,换句话说,就是函数A需要传递多个参数来使用,经过柯里化处理后成为函数B,只需传递一个或者一部分参数给函数B,它会返回一个函数去处理剩下的参数。

举个简单的例子:
- 开始的函数A

let fnA=function(x,y){
    return x+y
}
fnA(1,2) //3
  • 转化为柯里化后的函数B
let fnB=function(x){
    return function(y){
        return x+y
    }
}
fnB(1)(2)//3

柯里化后的函数看起来麻烦了呢,那为什么还要柯里化呢?我们先来实现个通用的柯里化函数,再分析其优点。

通用的柯里化函数

接下来我们实现一个函数,可以把多参数函数转变为单个(也支持传多个参数)参数函数。这个实现必须给定传参个数,只有个数按给定的传,才能得到相应结果。

   function curry(fn, length, ary) {
        length = length || fn.length;
        ary = ary || [];//记录所有传入的参数
        var slice = Array.prototype.slice;
        return function () {
            if (arguments.length < length) {
                Array.prototype.push.apply(ary, slice.call(arguments));//每次把参数合并到ary数组中
                return curry(fn, length - arguments.length, ary)//把还需传参的长度和已有参数数组传入curry,递归调用
            } else {
                return fn.apply(this, ary.concat(slice.call(arguments))); //调用求职函数,记得把此次传入的参数合并到ary数组再计算
            }
        };
    }


//函数的使用
let total = function () {
        let total = 0;
        [].slice.call(arguments).forEach(item => {
            total += item;
        });
        return total;
    };
 let fn = curry(total, 4);
 fn(1)(2)(3)(4);//10
 fn(1,2)(3)(4);//10

当然函数的柯里化不止一种实现,我们还可以使用以下这种方法,每次都只是合并参数到ary数组,最后用一个()来调用。好处是可以不限制传参数量,当不需要继续传参时,给个括号调用即可得到结果。

let currying = function (fn) {
             const ary= [];
             return function cb () {
                 if (arguments.length == 0) {//最后一个括号不传参,再调用函数
                     return fn.apply(this, args)
                 }
                 Array.prototype.push.apply(ary, Array.prototype.slice.call(arguments));
                 return cb;
             }
         }


//使用方法
let total = function () {
        let total = 0;
        [].slice.call(arguments).forEach(item => {
            total += item;
        });
        return total;
    };
 let fn = curry(total, 4);
 fn(1)(2)(3)(4)();//10
 fn(1,2)(3)(4)();//10

函数柯里化的优点

  • 延迟计算
    可以传递需要的参数,等到何时想要结果,再一并计算。
  • 参数复用
    有些参数相同,只需要传递一遍即可,不需要每次都传,太繁琐。
function ajax(url,type,data){
 // ...
}
ajax('www.my.com','GET',  "name=ko")
ajax('www.my.com','POST',  "name=koko")
//柯里化函数实现后(不再写柯里化后的函数,可根据通用自己实现,比较简单)
let newAjax=ajax('www.my.com')
newAjax('GET')("name=ko")
newAjax('POST')("name=koko")

你可能感兴趣的:(JavaScript)