深入理解函数式编程之柯里化

目录

柯里化定义

柯里化原因

柯里化前奏——需要固定数量参数

实现柯里化——期待固定数量参数

应用柯里化

流程剖析


柯里化定义

在数学和计算机科学中,柯里化是一种将使用多个参数的一个函数转化成一系列使用一个参数得函数的技术

In mathematics and computer science, currying is the technique of translating the evaluation of a function that takes multiple arguments(or a tuple of arguments)into evaluating a sequence of functions,each with a single argument

柯里化原因

前端使用柯里化的用途主要就应该是简化代码结构,提高系统的维护性,一个方法只有一个参数,强制了功能的单一性,很自然就做到了功能内聚,降低耦合。

柯里化的优点就是降低代码的重复,提高代码的适应性

调用形式

function add(a, b, c) {};
var newAdd = Curry(add);
newAdd(1)(2)(3)

柯里化前奏——需要固定数量参数

【例】

function add(a, b, c, d) {
    return a + b + c + d;
}
function FixedParmasCurry(fn) {
    var _arg = [].slice.call(arguments, 1);
    return function () {
        var newArg = _arg.concat([].slice.call(arguments, 0));
        return fn.apply(this, newArg);
    }
}
var newAdd = FixedParmasCurry(add, 1);
console.log(newAdd(2, 3, 4));

【结果】打印10

【分析】

第5行的arguments是第11行的实参[add,1],该行表示将arguments的第1位,即'1'添加给数组_arg;

第11行相当于

newAdd = function () {
    var newArg = _arg.concat([].slice.call(arguments, 0));
    return add.apply(this, newArg);
}

故其arguments是第12行的实参[2,3,4];第7行表示将数组_arg和arguments,即[2,3,4]拼接起来赋值给数组newArg。

【注】柯里化的传参方式(比较飘逸)

var newAdd = Curry(add);
newAdd(1, 2, 3, 4);
newAdd(1)(2, 3)(4);
newAdd(1, 2)(3, 4);
newAdd(1, 2)(3)(4);
newAdd(1)(2)(3)(4);

即只要满足固定参数即可;若传参不够的话打印NaN;若传参超出固定参数则忽略超出部分。

实现柯里化——期待固定数量参数

function add(a, b, c, d) {
    return a + b + c + d;
}
function FixedParmasCurry(fn) {
    var _arg = [].slice.call(arguments, 1);
    return function () {
        var newArg = _arg.concat([].slice.call(arguments, 0));
        return fn.apply(this, newArg);
    }
}
function Curry(fn, length) {
    //console.log(length);
    var length = length || fn.length;
    //console.log(length);  
    return function () {
        if (arguments.length < length) {
            var combined = [fn].concat([].slice.call(arguments, 0));
            return Curry(FixedParmasCurry.apply(this, combined),length - arguments.length)
        } else {
            return fn.apply(this, arguments);
        }
    }
}
var newAdd = Curry(add);
var num = newAdd(1)(2)(3)(4);

【结果】打印10

【问题】第11行的形参length的作用是什么

【解决】26行调用Curry时没有给length传参,因此12行打印undefined,在第13行中length =fn.length,即4,然后在第18行递归的过程中,形参length一直减小,arguments.length增大,直到传参的时候length减到0,再经过第13行使得length =fn.length= 4 = arguments.length,此时根据第16行判断跳出递归。

【问题】递归(未解决,再说吧,懵逼了)

应用柯里化

【例】

function ajax(method, url, data) {
    console.log(method, url, data);
}
var ajaxCurry = Curry(ajax);
var postAjax = ajaxCurry('post');
postAjax('www.test1.com',' name = jwh');
postAjax('www.test2.com', 'name = dqs');

【结果】

【例】

function ajax(method, url, data) {
    console.log(method, url, data);
}
var ajaxCurry = Curry(ajax);
var postAjax = ajaxCurry('post');
var getAjax = ajaxCurry('get');
postAjax('www.test1.com',' name = jwh');
getAjax('www.test2.com', 'name = dqs');

【结果】

流程剖析

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值