JavaScript函数柯里化的一些思考.docxVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
1.高阶函数的坑 在学习柯里化Z前,我们首先来看下面一段代码: var fl = function(x){ return f(x); }; fl(x); 很多同学都能看出来,这些写是非常傻的,因为函数歸和f是等效的,我们宜接令var fl =f;就行了,完全没有必要包裹那么一层。 但是,卜而一段代码就未必能够看得出问题来了: var getServerstuff = function(callback){ return ajaxCall(function(json){ return callback(json); }); }; 这是我摘自《JS函数式编程指南》中的一段代码,实际上,利用上面的规则,我们可以得 ill callback 与函数 function(json){return callback(json);}; 是等价的,所以函数可以化简为: var getServerstuff = function(callback){ return ajaxCall(callback); }; 继续化简: var getServerstuff = ajaxCall; 如此一来,我们发现那么氏一段程序都白写了。 函数既可以当参数,乂可以当返回值,是高阶函数的一个重要特性,但是稍不留神就容易踩 到坑里。 2.函数柯里化(curry) 言归正传,什么是函数柯里化?函数柯里化(cmry)就是只传递给函数一部分参数来调用 它,让它返冋一个函数去处理剩下的参数。听得很绕1丨,其实很简单,其实就是将函数的变 量拆分开来调用:f (x,y, z) - f (x) (y) (z) o 对于最开始的例子,按照如下实现,要传入两个参数,fl调用方式是fl(fzX)o var fl = function (f, x) { return f(x); }; 注意,由于f是作为一个函数变最传入,所以门变成了一个新的函数。 我们将曰变化一下,利用闭包可以写成如下形式,则現调用方式变成Tfi(f)(x),而且 得到的结果完全一样。这就完成了 fi的柯里化。 var fl = function (f) { return function(x){ return f(x); } }; var f 2 = f 1 (f); f2 (x); 其实这个例子举得不恰当,细心的同学可能会发现,珂虽然是一个新函数,但是^和f是 完全等效的,绕了半天,还是绕回来了。 这里有一个很经典的例子: [11 , ll* , ?11] .map(parselnt) // [ 11, NaNz 3 ] [11 , ll , ll] .map(fl(parselnt)) //[ llz 11, 11 ] 由于parselnt接受两个参数,所以直接调川会冇进制转换的问题,参考“不愿相离的文章。 var f2 = fl (parselnt) , f2 It parselnt由原来的接受两个参数变成了只接受一个参数的 新两数,从而解决这个进制转换问题。通过我们的佯包裹以后就能够运行出正确的结果了。 有同学觉得这个不算柯里化的应用,我觉得还是算吧,各位同学可以一起來讨论下。 3?函数柯里化进一步思考 如果说上一节的例了中,我们不是直接运行f(x),而是把函数f当做一个参数,结果会怎 样呢?我们来看下面这个例了: 假设fl返回函数g, g的作用域指向xs,函数f作为g的参数。最终我们可以写成如下形 式: var fl = function(f,xs){ return g.call(xs,f); }; 实际上,用fl来替代g.call (xxx)的做法叫反柯里化。例如: var forEach = function(xs,f){ return Atotype ?forEach.call(xs,f); }; var f = function (x) {console ?log(x);}; var xs = {0:1peng1,1:1chen1,length:2}; forEach(xs,f); 反curring就是把原來已经固定的参数或者this上下文等当作参数延迟到未來传递。 它能够在很大程度上简化换数,前提是你得习惯它。 抛开反柯里化,如果我们要柯里化fl怎么办? 使用闭包,我们可以写成如下形式: var fl = function(f){ return function(xs){ return g ? call(xs z f); } }; var f2 = f 1 (f); f2(xs); 把f传入fl中,我们就可以得到f2这个新函数。 只传给两数一部分参数通常也叫做局部调用(partial application),能够人量减少样板文件代码(boilerplate code) o 当然,函数fl传入的

文档评论(0)

ggkkppp + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档