这篇文章写的很全面,不过也啰嗦:http://benalman.com/news/2012/09/partial-application-in-javascript/

这篇文章是神级运用:http://osteele.com/sources/javascript/functional/

绑定变量

假设我们函数的部分参数已经固定,我们可以绑定这个参数,生成新的函数。

// 一般函数
function add(a, b) {
return a + b;
} // 特定情况的函数生成函数
function makeAdder(a) {
return function(b) {
return a + b;
};
} // 特定函数
var addOne = makeAdder(1);
addOne(2); //
addOne(3); //

这里实现有两个重要的知识点,1.javascript允许函数访问外部变量(详细见javascript的闭包概念)。2.在javascript里,函数是可以将函数作为参数和返回值。

绑定函数

有时候我们需要绑定的不只是数值

// 特定函数生成函数
function bindFirstArg(fn, a) {
return function(b) {
return fn(a, b);
};
} // 一般函数
function add(a, b) {
return a + b;
} // 特定函数
var addOne = bindFirstArg(add, 1);
addOne(2); //
addOne(3); //

由于函数可以作为参数,所以我们还可以实现函数绑定。

部分函数应用

部分函数应用可以解释为,将一个函数和它一些的参数绑定,然后返回一个新的函数,这个新函数继续接收剩下未绑定的参数。

它与bind()方法原理上有些相似。

注意:arguments 对象是一个类数组对象,当函数被调用时创建,只有在函数内部可以引用,它包括所有传入函数的参数。

下面的部分应用函数,和使用实例。

function partial(fn /*, args...*/) {
var slice = Array.prototype.slice;
var args = slice.call(arguments, 1); return function() {
return fn.apply(this, args.concat(slice.call(arguments, 0)));
};
}

下面是一个使用部分函数的例子:

function add(a, b) {
return a + b;
} var addOne = partial(add, 1);
addOne(2); //
addOne(3); //

下面分析一下是怎么工作的,为了将arguments转化为数组,就要使用数组的方法Array.prototype.slice,因为要使用两次,所以存储到slice缓存。partial函数将它的参数除第一个fn外,存储到args上,以便返回函数访问。当返回函数f调用时,再将新arguments对象转化为数组,利用数组方法Array.prototype.concat将两个数组合并,再利用apply调用fn,this是window,参数就是先前合并的参数,f的返回值就是fn的返回值。

注意,他是利用apply可以接收数组的特性,将两个函数的参数转成数组再合并,以此保证绑定函数参数的长度可以不固定。

也可以这样调用函数

Function.prototype.partial = function() {
var fn = this, args = Array.prototype.slice.call(arguments);
return function() {
return fn.apply(this, args.concat(
Array.prototype.slice.call(arguments)));
};
};

javascript中函数this指向调用它的对象。又函数的都是继承自函数的原型,所以可以String.prototype.split.partial()调用partial,而this指向的是split,这也就是partial的fn。

如何跳跃式绑定参数值?

Function.prototype.partial = function(){
var fn = this, args = Array.prototype.slice.call(arguments);
return function(){
var arg = 0;
for ( var i = 0; i < args.length && arg < arguments.length; i++ )
if ( args[i] === undefined )
args[i] = arguments[arg++];
return fn.apply(this, args);
};
};

思路就是,如果想跳跃的参数值为undefined,在返回函数f里,对先前值为undefined进行覆盖。

部分函数应用到底有什么用?

以下例子基于上面的partial。

String.prototype.csv = String.prototype.split.partial(/,\s*/);

  var results = "John, Resig, Boston".csv();
alert( (results[1] == "Resig") + " The text values were split properly" );

这里我们返回一个函数,保存到String.prototype.csv中,每个字符串默认就可以用csv进行字符串拆分。

var delay = setTimeout.partial(undefined, 10);

  delay(function(){
alert( "A call to this function will be temporarily delayed." );
});

这里我们返回一个默认延迟为10的函数,可以一定程度上简化调用。

var bindClick = document.body.addEventListener
.partial("click", undefined, false); bindClick(function(){
alert( "Click event bound via curried function." );
});

简化事件监听。

这个技术可以用于特定情况,构造简化的API。

javascript中的部分函数应用的更多相关文章

  1. 浅谈JavaScript中的函数问题

    前面的话:JavaScript可运行在所有主要平台的主流浏览器上,也可运行在每一个主流操作系统的服务器端上.所以呢,要想成为一名优秀的全栈工程师,必须懂得JavaScript语言.这是我整理的JS的部 ...

  2. javascript中的Array对象 —— 数组的合并、转换、迭代、排序、堆栈

    Array 是javascript中经常用到的数据类型.javascript 的数组其他语言中数组的最大的区别是其每个数组项都可以保存任何类型的数据.本文主要讨论javascript中数组的声明.转换 ...

  3. javascript中的this与函数讲解

    前言 javascript中没有块级作用域(es6以前),javascript中作用域分为函数作用域和全局作用域.并且,大家可以认为全局作用域其实就是Window函数的函数作用域,我们编写的js代码, ...

  4. JavaScript 中的数据类型

    Javascript中的数据类型有以下几种情况: 基本类型:string,number,boolean 特殊类型:undefined,null 引用类型:Object,Function,Date,Ar ...

  5. javascript中的操作符详解1

    好久没有写点什么了,根据博主的技术,仍然写一点javascript新手入门文章,接下来我们一起来探讨javascript的操作符. 一.前言 javascript中有许多操作符,但是许多初学者并不理解 ...

  6. 掌握javascript中的最基础数据结构-----数组

    这是一篇<数据结构与算法javascript描述>的读书笔记.主要梳理了关于数组的知识.部分内容及源码来自原作. 书中第一章介绍了如何配置javascript运行环境:javascript ...

  7. javascript中变量提升的理解

    网上找了两个经典的例子 var foo = 1; function bar() { if (!foo) { var foo = 10; } alert(foo); } bar(); // 10 var ...

  8. 前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型

    前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话): 有人说拖延症是一个绝症,哎呀治不好了.先不说这是一个每个人都多多少少会有的,也不管它究竟对生活有多么大的 ...

  9. 简单分析JavaScript中的面向对象

    初学JavaScript的时候有人会认为JavaScript不是一门面向对象的语言,因为JS是没有类的概念的,但是这并不代表JavaScript没有对象的存在,而且JavaScript也提供了其它的方 ...

随机推荐

  1. Linux常用C函数---字符串转换篇

    函数讲解部分参考http://net.pku.edu.cn/~yhf/linux_c/ atof(将字符串转换成浮点型数) 相关函数 atoi,atol,strtod,strtol,strtoul 表 ...

  2. 我使用过的Linux命令之file - 检测并显示文件类型

    摘自:http://codingstandards.iteye.com/blog/804463 我使用过的Linux命令之file - 检测并显示文件类型 用途说明 file命令是用来检测并显示文件类 ...

  3. SQL_SERVER日期函数详细用法

    1.一个月第一天的 Select DATEADD(mm, DATEDIFF(mm,0,getdate()), 0) 2.本周的星期一 Select DATEADD(wk, DATEDIFF(wk,0, ...

  4. 步步学LINQ to SQL:使用LINQ检索数据【转】

    [IT168 专稿]该系列教程描述了如何采用手动的方式映射你的对象类到数据表(而不是使用象SqlMetal这样的自动化工具)以便能够支持数据表之间的M:M关系和使用实体类的数据绑定.即使你选择使用了自 ...

  5. CSS备忘-1

    CSS 可以通过以下方式添加到HTML中: 内联样式- 在HTML元素中使用"style" 属性 内部样式表 -在HTML文档头部 <head> 区域使用<sty ...

  6. 深入解析CSS样式层叠权重值

    本文为转载内容,源地址:http://www.ofcss.com/2011/05/26/css-cascade-specificity.html 读到<重新认识CSS的权重>这篇,在文章最 ...

  7. 【27前端】背景半透明rgba LESS实践

    今天有看到司徒正美<背景半透明rgba最佳实践>的文章和里面推荐的一个在线工具CSS背景颜色属性值转换  . 于是联系到自己的less库,新技能Get. 内容如下: /*在你的less库中 ...

  8. Silverlight学习(五)图形标绘

    Silverlight中进行图形标绘的方法太多了,这里的标绘和Arcgis中的标绘不同,这里大多是静态的标绘.标绘的方法主要有Path(路径标记法).直接标绘(Line等).几何标记(LineGeom ...

  9. Struts2 访问web元素

    访问web元素的四种方法(耦合,依赖注入).(耦合,非依赖注入).(非耦合,依赖注入).(非耦合,非依赖注入) 耦合:可以得到HttpServletResponse,HttpServletReques ...

  10. jsp页面适应手机页面

    <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scal ...