目录
柯里化定义
在数学和计算机科学中,柯里化是一种将使用多个参数的一个函数转化成一系列使用一个参数得函数的技术
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');
【结果】
流程剖析