柯里化(Currying),又称部分求值(Partial Evaluation),是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。
简单理解:参数部分使用。外部函数处理部分应用,剩下的由外部函数的返回函数处理。
柯里化有3个作用:1. 参数复用;2. 提前返回;3. 延迟计算/运行(实际项目中用的很少,但是ES5中的bind方法的本质就是用的函数柯里化,不考虑执行时的新增参数)。
这里只讲参数复用和提前返回的两个常见用法:
1.参数复用:
// 一般函数写法
function sum (x, y) {
return x + y
}
console.log('普通函数求和', sum(10, 20))
// 函数柯里化写法
function sum_curry (x) {
return function (y) {
return x + y
}
}
// 设置默认第一参数
var addTen = sum_curry (10) // 30
// 设置其它部分参数
console.log('函数柯里化', addTen(40)) // 50
2.提前返回
“提前返回”,很常见的一个例子,兼容现代浏览器以及IE浏览器的事件添加方法
一般写法
var addEvent = function(el, type, fn, capture) {
if (window.addEventListener) {
el.addEventListener(type, function(e) {
fn.call(el, e);
}, capture);
} else if (window.attachEvent) {
el.attachEvent("on" + type, function(e) {
fn.call(el, e);
});
}
};
上面的方法有什么问题呢?很显然,我们每次使用addEvent为元素添加事件的时候,(eg. IE6/IE7)都会走一遍if...else if ...,其实只要一次判定就可以了,怎么做?–柯里化。改为下面这样子的代码:
函数柯里化写法
var addEvent = (function(){
if (window.addEventListener) {
return function(el, sType, fn, capture) {
el.addEventListener(sType, function(e) {
fn.call(el, e);
}, (capture));
};
} else if (window.attachEvent) {
return function(el, sType, fn, capture) {
el.attachEvent("on" + sType, function(e) {
fn.call(el, e);
});
};
}
})();
总结:
张鑫旭
。
其实这些模式在实际使用的时候,或多或少都使用过,当看到“模式”概念的时候,我们就会猛然惊起:“哦,原来这个就叫做‘观察者模式’等”。现在要讨论的问题是,我们有没有必要把这些“模式”都记住呢,都理解其对应的核心呢?这个问题类似于,我可以看懂NBA的篮球比赛,那我有没有必要把各个球队以及球队的队员都记住呢?
如果想成为JS大神,从这个目标来看,这是需要的;好比优秀的篮球解说员必须要知道每个球队的名字、球员甚至周边八卦。但是,现实很重要。如果连JS函数相关的基本东西都驾驭不好,显然,硬是啃这些似懂非懂的概念只会造成混乱。如果你觉得可以更近一步,先通透几个自己习惯的熟悉的使用模式,足够应付实际项目;其他一些概念什么的,更多的只是噱头,实用性其实并不大。正如本文的柯里化,看上去很高级,似乎也有点用处,然而JS的灵活性使得很多实现完全摆脱“柯里化”这个概念的束缚,以更通俗易懂的方式实现。
然而,即使实用性不高,我们还是要有所了解,因为,你不知道什么时候会用到它。比方说CSS中的display:table;
某些情况下可以解决一些棘手问题(secret!
).
因此,本文的柯里化至少要知道个大概,如果你囫囵吞枣式的看到此处,只记得“柯里化==柯南”,你可以再稍微静点心重新看一下。我的笔头要比嘴巴犀利的多,因为,文字我可以静心琢磨:“如何讲述才能提起兴趣,才能让新手也能知其意会其形?” ,久而久之,就形成了这种菊紧的风格——更适合新手阅读,同时被“高人”不屑:“写得太罗嗦啦,直接一句话不就完事啦!”还时不时来一句“鉴定完毕”,恩,挺适合去验尸!
参考文章
张鑫旭
网友评论