函数柯里化:柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,而且返回接受余下的参数且返回结果的新函数的技术。是否有些不太懂?好吧,用段代码来解释下。html
function saySTS(something) {前端
return function(someboby) {ajax
alert(something + "!" + sombody);编程
}json
}闭包
saySTS函数就是用来讲些什么(something)对某人(somebody);这就是柯里化的函数。dom
-------------------------------------------------------------------------------------------------------------------------------------------------------异步
咱们来看下若是不用柯里化来怎么实现。async
function saySTS(something, somebody){函数式编程
alert(something + "!" + sombody);
}。
--------------------------------------------------------------------------------------------------------------------------
也许你会问我函数柯里化到底有什么用,不就是把多个参数的函数转换成多个单参数函数吗?下面我拿实际前端开发中的例子来解释。
如今有这么一个问题模型:
你要开发一个抽奖活动页面,后台开发人员要跟您定一个抽奖接口,这个接口会根据不一样的抽奖选项返回不一样的抽奖信息。请求的接口的几个地址:"action.do?state=0","action.do?state=1","action.do?state=2".
假如这些接口是根据3种不一样积分,来进行相应的抽奖活动,30积分抽奖的奖品,60积分抽奖的奖品,120积分抽奖的奖品,返回的接口多是{中奖信息,抽奖剩余分数,中奖纪录,抽了多少次奖,剩余抽奖次数等等}。
此时你前端有6处须要根绝返回的接口数据进行显示或者交互操做,简化一点div#01, div#02, div#03, div#04, div#05, div#06.这几块要显示剩余的抽奖次数。
若是不用柯里化我会这样作
function render(url) {
$.ajax({
type:"post",
url:url,
cache:false,
async:true,
dataType:"json",
data:params,
//当异步请求成功时调用
success: function(data, status){
//此行可能你还须要对数据进行一些处理。总之在你拿数据渲染你的dom节点前或许还要作点别的。
$("div#01").html(data.times);//例子比较简单,可能你须要作的不仅这些还有不少。抽奖的提示信息。
//等等其余操做.......
},
//当请求出现错误时调用
error: function(err){
alert("error : "+err);
}
})
}
很显然这样的代码耦合性很强,不太利于扩展跟维护.并且返回的数据我也不必定非得作html(data.times)这样的操做。把返回后的信息所有集中处理,这样不好。
改进下咱们把成功以后的要处理的操做单独提取出来放在一个咱们都会叫出来的名字callback
function callback(item, data) { //终于把耦合的代码搞出来了,item多是div#01, div#02, div#03, div#04, div#05, div#06
$(item).html(data.times);
}
//这里咱们假设后台人员只开发了一个接口,以致于我想查询剩余次数显示在相应的信息栏上也要返回(最近中奖纪录,剩余分数等)这些数据
//固然这是很失败的接口,通常接口只须要返回前端想要的数据便可。
function callback02(item, data) { //也许我也想作callback02这样的操做等,render都是能够支持的
return function(data){
$('item').click(function(e){
alert(data.gift);
})
}
}
function render(url, item, callback) {
$.ajax({
//一些代码不重复
success: function(data, status){
//此行可能你还须要对数据进行一些处理。总之在你拿数据渲染你的dom节点前或许还要作点别的。
callback(item, data);
},
error: function(err){
alert("error : "+err);
}
})
}
这样咱们就能够对div#01 div#02 等要操做的dom节点灵活的,并且操做方式能够多变化。
可是有一天忽然要作这么一件事儿,我不光要显示剩余次数,并且还要把礼品等等一切信息在前端显示出来
function callback03(data) { //这个过程不只仅想知道msg或者gift
//针对一个前端抽奖模块进行全面的渲染。
//不一样的几个前端模块我要显示全部关于本人中奖的信息(抽中多少次,中过什么奖啊等等)
}
等等,咱们的render函数有三个参数,这个callback03是否是不符合规定啊,咱们还须要item
由于render里面的callback咱们是这样调用的callback(item, data);
很显然render已经不适合新的callback03了,再写一个差很少的render?重复不少代码只是在callback(item, data)有些不同的新的处理函数?
不,显然不须要,咱们不能这样作,这是很冗余的。那咱们怎么办?
您可能在想:come on!My man(丹泽尔华盛顿在美国黑帮的一句口头禅,非常喜欢),来点正题吧!
好吧,来个柯里化过的函数吧。
首先改变render函数改为更灵活的。让他专一于作一件事。就是处理callback,不要加上item。
function render(url, callback) {
$.ajax({
//一些代码不重复
success: function(data, status){
//此行可能你还须要对数据进行一些处理。总之在你拿数据渲染你的dom节点前或许还要作点别的。
callback(data);
},
error: function(err){
alert("error : "+err);
}
})
}
但是callback, callback02个人这两个小伙伴们怎么办? 若是你给改了他们两个要怎么办?由于render已经不支持他们了。
别急,咱们把这两个小伙伴们打扮下。
function update(item) {
return function(data) {
$(item).html(data);
}
}
function update02(item) {
return function(data){
$('item').click(function(e){
alert(data.gift);
})
}
}
function render(url, callback) {
$.ajax({
//一些代码不重复
success: function(data, status){
//此行可能你还须要对数据进行一些处理。总之在你拿数据渲染你的dom节点前或许还要作点别的。
callback(data);
},
error: function(err){
alert("error : "+err);
}
})
}
render("action.do?state=0", update("div#01"));
render("action.do?state=0", update("div#02"));
render("action.do?state=0", update02("div#01"));
render("action.do?state=0", update02("div#02"));
柯里化是函数式编程重要标志,这个demo借助匿名和闭包完成了函数柯里化,函数式编程一切皆为函数。函数式编程灵活性和执行效率很高,可是总体逻辑不太好捋。
但愿你们能提出一些本身的建议。