何为柯里化
概念:在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的
参数且返回结果是新函数的技术。
上栗子
var add = function(x) {
return function(y) {
return x + y;
}
}
var increment = add(1);
var addTen = add(10);
increment(2);
// 3
addTen(2);
// 12
解释:我们定义了一个add函数,这个函数接受一个参数并返回一个新的函数。调用add之后,返回的函数通过闭包可以访问到add的第一个参数。这样可以使这类函数的定义和调用更加容易。
进阶(for our enjoyment)
var curry = require('lodash').curry;
var match = curry(function(what, str) {
return str.match(what);
})
var replace = curry(function(what, replacement, str) {
return str.replace(what, replacement);
})
var filter = curry(function(f, array){
return array.filter(f);
})
match(/s+/g, 'hello world');
// [' ']
match(/s+/g)('hello world');
//[' ']
var hasSpaces = match(/s+/g);
// function(x) { return x.match(/\s+/g) }
hasSpaces('hello world');
//[' ']
hasSpaces('sssss');
// null
var noVowels = replace(/[aeiou]/ig);
// function(replacement, x) { return x.replace(/[aeiou]/ig, replacement) }
var censored = noVowels("*");
// function(x) { return x.replace(/[aeiou]/ig, "*") }
censored("Chocolate Rain");
// 'Ch*c*l*t* R**n'
filter(hasSpaces, ["tori_spelling", "tori amos"]);
// ["tori amos"]
var findSpaces = filter(hasSpaces);
// function(xs) { return xs.filter(function(x) { return x.match(/\s+/g) }) }
findSpaces(["tori_spelling", "tori amos"]);
// ["tori amos"]
这里表明的是一种“预加载”函数的能力,通过传递一到两个参数调用函数,就能得到一个记住了这些参数的新函数。
当我们谈论纯函数的时候,我们常说函数接受一个输入返回一个输出。currying函数所做的正是这样:每传递一个参数调用函数,就返回一个新函数处理剩余的参数。
柯里化的好处
通过简单地传递几个参数,就能动态创建实用的新函数;而且还能带来一个额外好处,那就是保留了函数定义,尽管参数不止一个
如何实现柯里化
var add = function(){
var sum = 0;
for(var i = 0, l = arguments.length; i < l; i++){
sum += arguments[i];
}
return sum;
}
var curry = (function(fn){
var args = [];
return function(){
if(arguments.length == 0) {
return fn.apply(this, args)
} else {
[].push.apply(args, arguments);
return arguments.callee;
}
}
})
currySum = curry(add);
currySum(1, 2, 3);
currySum(1);
currySum(1);
currySum(1);
currySum(1);
currySum();
// 10