javascript之Partial Application学习


Posted in Javascript onJanuary 10, 2013

这一次来学习一下Partial Application。我们先看一下函数的介绍,在维基上有简单的介绍:
在数学中,一个函数是描述每个输入值对应唯一输出值的这种对应关系,符号为 f(x)。例如,表达式 f(x)=x2表示了一个函数 f,其中每个输入值x都与唯一输出值x2相联系。

因此,如果一个输入值为3,那么它所对应的输出值为9。而g(x,y) = xy有两个参量x和y,以乘积xy为值。上面描述了函数(为方便假设x,y都是int),并且给出了函数的两个例子,先换一种方式来看,f(x)可以表示为:x -> y(x2),即经经过f到x2的映射,写成 int -> int。

接受一个int 返回一个int。再看g(x,y)可以表示为:x -> y -> z(xy)。即x,y经过g的映射到z,写成 int -> int -> int。我们看g(x,y)函数,用javascript来实现一下:

function g(x,y){ 
return x*y; 
}

很完美啊,很接近数学定义。它依次接受两个参数,x与y。并且返回它们两个的乘积。但是当x是个常数,比如x=n(n是一个自然数)。那么g(n,y)=ny。这就变成一个常数与一个变量的乘积,它接受一个参数y返回ny,即y -> z(ny) 的映射,写成 int -> int。因此,我们可以这样来理解上面的工作,g(x,y)是接受一个参数int,并且返回一个函数 int ->int 。这个返回的函数只接受一个int 并且返回一个int。来用javascript表示一下:
var h = g(2);

这里的h表示函数h(y)=2y。这样就有h(5)=10,h(13)=26等。
h(5); 
h(13);

这个技术是把需要多个参数的函数形式转变为接受单个参数的函数链,它通常叫做Curring,这是为了纪念Haskell Curry而起的名字,但他并不是第一个提出的1。但是很遗憾的是javascript并不支持这样的特性。所以要实现这样的特性需要做一些工作,这些工作并不复杂。主要是把参数存储起来,等待调用函数链上的下一个函数时拿出前边参数继续传递给链上的下一个函数,直到最后得到返回值。先看一下下面的代码:
function atarr(a,index){ 
var index=index||0,args = new Array(a.length - index); 
for(var i in a){ 
if(i>=index) args[i-index]=a[i]; 
} 
return args; 
} 
function m(scope,fn){ 
if(arguments.length<3) return fn.call(scope); 
var p = atarr(arguments,2); 
return function(){ 
var args = atarr(arguments); 
return fn.apply(scope,p.concat(args)); 
} 
}

测试代码:
var plus = function(a,b){ 
return a+b; 
}; 
var plus2 = m(null,plus,2); 
console.log(plus2(10)); 
console.log(plus2(0)); 
//结果 
12 
2

这样我们的目标已经实现啦。在上面的atarr函数是将arguments对象中指定位置开始的参数取出并且保存到一个数组中。m函数就是主角,它完成了前面定义的任务,实现了保存函数链上的参数并且返接受余下参数的函数。测试代码中的plus函数原先接受a,b两个参数并返回a与b之和,即 int -> int -> int,而plus2则变成了接受一个参数b与2相加,并返回2与b之和,即 int -> int。

通过上面的一些工作,我们实现了javascript中的Partial Application,在dojo框架中hitch2实现了域绑定和partial。有兴趣可以读一下它的源码,也是非常简单明了的。

Javascript 相关文章推荐
JavaScript中switch判断容易犯错的一个细节
Aug 27 Javascript
jQuery中:lt选择器用法实例
Dec 29 Javascript
jQuery使用toggleClass方法动态添加删除Class样式的方法
Mar 26 Javascript
使用AngularJS创建单页应用的编程指引
Jun 19 Javascript
jQuery中serializeArray()与serialize()的区别实例分析
Dec 09 Javascript
javascript运动框架用法实例分析(实现放大与缩小效果)
Jan 08 Javascript
轻松实现Bootstrap图片轮播
Apr 20 Javascript
浅谈JavaScript对象的创建方式
Jun 13 Javascript
Javascript将数值转换为金额格式(分隔千分位和自动增加小数点)
Jun 22 Javascript
Mongoose学习全面理解(推荐)
Jan 21 Javascript
详解原生JS动态添加和删除类
Mar 26 Javascript
nuxt.js添加环境变量,区分项目打包环境操作
Nov 06 Javascript
javascript之典型高阶函数应用介绍二
Jan 10 #Javascript
javascript之典型高阶函数应用介绍
Jan 10 #Javascript
根据json字符串生成Html的一种方式
Jan 09 #Javascript
web的各种前端打印方法之jquery打印插件jqprint实现网页打印
Jan 09 #Javascript
web的各种前端打印方法之jquery打印插件PrintArea实现网页打印
Jan 09 #Javascript
实现web打印的各种方法介绍及实现代码
Jan 09 #Javascript
js去除重复字符串两种实现方法
Jan 09 #Javascript
You might like
文章推荐系统(三)
2006/10/09 PHP
最令PHP初学者们头痛的十四个问题
2007/01/15 PHP
Php output buffering缓存及程序缓存深入解析
2013/07/15 PHP
Symfony2实现在controller中获取url的方法
2016/03/18 PHP
js multiple全选与取消全选实现代码
2012/12/04 Javascript
javascript的offset、client、scroll使用方法详解
2012/12/25 Javascript
js汉字转拼音实现代码
2013/02/06 Javascript
javascript遍历控件实例详细解析
2014/01/10 Javascript
js实现一个链接打开两个链接地址的方法
2015/05/12 Javascript
JavaScript实现文字跟随鼠标特效
2015/08/06 Javascript
jQuery焦点图插件SaySlide
2015/12/21 Javascript
JavaScript地理位置信息API
2016/06/11 Javascript
vue实现导航栏效果(选中状态刷新不消失)
2017/12/13 Javascript
JavaScript数组排序reverse()和sort()方法详解
2017/12/24 Javascript
JavaScript学习总结(一) ECMAScript、BOM、DOM(核心、浏览器对象模型与文档对象模型)
2018/01/07 Javascript
微信小程序实现自定义picker选择器弹窗内容
2020/05/26 Javascript
egg.js的基本使用和调用数据库的方法示例
2019/05/18 Javascript
[46:57]EG vs Winstrike 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
Python实现确认字符串是否包含指定字符串的实例
2018/05/02 Python
对numpy中的数组条件筛选功能详解
2018/07/02 Python
wxPython色环电阻计算器
2019/11/18 Python
谈谈Python:为什么类中的私有属性可以在外部赋值并访问
2020/03/05 Python
html5定制表单_动力节点Java学院整理
2017/07/11 HTML / CSS
利用canvas实现图片压缩的示例代码
2018/07/17 HTML / CSS
介绍一下木马病毒的种类
2015/07/26 面试题
教师的实习鉴定
2013/12/15 职场文书
写自荐信要注意什么
2013/12/26 职场文书
市政管理求职信范文
2014/05/07 职场文书
创意婚礼策划方案
2014/05/18 职场文书
教师工作失职检讨书
2014/09/18 职场文书
2014年纪检监察工作总结
2014/11/11 职场文书
承诺函格式模板
2015/01/21 职场文书
劳动仲裁代理词范文
2015/05/25 职场文书
排球赛新闻稿
2015/07/17 职场文书
解决Tkinter中button按钮未按却主动执行command函数的问题
2021/05/23 Python
为什么RedisCluster设计成16384个槽
2021/09/25 Redis