javascript里的偏函数——本质函数式编程+闭包,返回函数
最终效果:
var greet = function(greeting, name) {
return greeting + ' ' + name;
};
var sayHelloTo = _.partial(greet, 'hello');
sayHelloTo('fred');
// => 'hello fred'
来自:http://lodashjs.com/docs/#_partialfunc-partials
除非你已经使用过其他的函数式编程,不然你可能对下面这两个概念很陌生:“偏函数应用”和“函数柯里化“。
偏函数应用,英文是partial application,也可以译作“局部应用”、“部分应用”、“偏应用”
函数柯里化,英文是currying,也可以译作“局部套用”、“加里化”、“卡瑞化”
话虽如此,但是假如你一旦理解了这两个概念,你就完全可以在自己的代码里使用他们。
Functions
即使你已经很熟悉JavaScript的function, 知道function可以作为返回值,可以作为参数。
但是我还是推荐你读一下这个第一部分。如果不需要,也可以跳过,直接看局部应用的章节。
我们首先看一个非常基础的例子:
function add(a, b) {
return a + b;
}
add(1, 2); // 3
add(1, 3); // 4
add(1, 10); // 11
add(1, 9000); // 9001
尽管上面的例子是非常的简单,但是还是演示出了我们反复调用一个function的场景,并且每次传入的第一个参数都是相同的,在上面的代码里就是数字1
Functions返回Functions
我们也可以创建一个叫做makeAdder的function,这个function会返回另一个可以传入参数的function。(像这种可以用来创建其他function或object的function,一般会叫做工厂 - factories)
返回的函数,如果往里面传入参数调用,可以把传入的参数值和原来设的参数值,返回相加的结果。
// More general function.
function add(a, b) {
return a + b;
}
add(1, 2); // 3
add(10, 3); // 13
// More specific function generator.
function makeAdder(a) {
return function(b) {
return a + b;
};
}
// More specific functions.
var addOne = makeAdder(1);
addOne(2); // 3
addOne(3); // 4
var addTen = makeAdder(10);
addTen(2); // 12
addTen(3); // 13
上面的代码之所以可行,是因为JavaScript支持闭包的功能,由于闭包的存在,使得function可以访问到这个function外部的变量,甚至在调用这个function时的作用域的外层。
除此之外,在JavaScript里面,function是一等公民。正因为如此,function可以接受function作为参数,也可以返回function.
闭包和函数这个一等公名经常一起配合着工作:使得返回的function可以继续使用传入的参数。
上面的代码给我们提供了一些方便,我们可以不再使用add(1, 2),而直接使用addOne(2),但是实现这个并不是不需要付出代价的。
首先,实际做加法的逻辑在上面两个例子的代码中还是重复的,这样还是会有些问题。
其次,对每个类似于上面的加法场景,用这种方式去独立除不同的逻辑,我们将需要手工创建makeSomething的工厂function。
Functions接受Functions
下面的逻辑步骤是创建一个更普遍的工厂function,不仅接受一个要绑定的参数,也会接受一个function,这个function里面包含了所有的核心逻辑。(传入到其他function的function,一般被成为回调函数-callbacks)
用这种方式,一个单独的工厂function能够被用来创建function绑定。
注意,原始的function被没有被更新,并且他们的行为也不会改变。他们很容易被调用。
// Relatively flexible, more specific function generator.
function bindFirstArg(fn, a) {
return function(b) {
return fn(a, b);
};
}
// More general functions.
function add(a, b) {
return a + b;
}
add(1, 2); // 3
function multiply(a, b) {
return a * b;
}
multiply(10, 2); // 20
// More specific functions.
var addOne = bindFirstArg(add, 1);
addOne(2); // 3
addOne(3); // 4
addOne(10); // 11
addOne(9000); // 9001
var multiplyByTen = bindFirstArg(multiply, 10);
multiplyByTen(2); // 20
multiplyByTen(3); // 30
multiplyByTen(10); // 100
multiplyByTen(9000); // 90000
上面这段代码,亮点不在于它可以将某个参数绑定到任意的function,并且这个参数作为绑定的function的第一个参数,它还能将方法绑定它自己身上作为第一个参数,因此创建了一个可绑定的function
想想这种情况:假如bindFirstArg能够将第一个参数绑定到一个function,但是这个function可以接受两个参数,比如传进去1和10,1用来加,10用来乘。
bindFirstArg可以接受两个2参数,假如第一个参数是它自己,也就是bindFirstArg可以用来绑定它自己。
看下面的例子:
// More specific function generator.
var makeAdder = bindFirstArg(bindFirstArg, add);
// More specific functions.
var addOne = makeAdder(1);
addOne(2); // 3
addOne(3); // 4
var addTen = makeAdder(10);
addTen(2); // 12
addTen(3); // 13
javascript里的偏函数——本质函数式编程+闭包,返回函数的更多相关文章
- python函数式编程之返回函数、匿名函数、装饰器、偏函数学习
python函数式编程之返回函数 高阶函数处理可以接受函数作为参数外,还可以把函数作为结果值返回. 函数作为返回值 def laxy_sum(*args): def sum(): ax = 0; fo ...
- Learning Python 012 函数式编程 2 返回函数 匿名函数 装饰器 偏函数
Python 函数式编程 2 返回函数 返回函数的意思就是:函数作为返回值.(高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回.) 举个例子:实现一个可变参数的求和. 正常的函数: de ...
- Python学习札记(二十四) 函数式编程5 返回函数
参考:返回函数 NOTE 1.高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回. eg.求和函数 #!/usr/bin/env python3 def calsums(*args): a ...
- JavaScript函数式编程(纯函数、柯里化以及组合函数)
JavaScript函数式编程(纯函数.柯里化以及组合函数) 前言 函数式编程(Functional Programming),又称为泛函编程,是一种编程范式.早在很久以前就提出了函数式编程这个概念了 ...
- 【Python】[函数式编程]高阶函数,返回函数,装饰器,偏函数
函数式编程高阶函数 就是把函数作为参数的函数,这种抽象的编程方式就是函数式编程.--- - -跳过,不是很理解,汗 - ---
- 从函数式编程到Ramda函数库(二)
Ramda 基本的数据结构都是原生 JavaScript 对象,我们常用的集合是 JavaScript 的数组.Ramda 还保留了许多其他原生 JavaScript 特性,例如,函数是具有属性的对象 ...
- 从函数式编程到Ramda函数库(一)
函数式编程是种编程方式,它将电脑运算视为函数的计算.函数编程语言最重要的基础是λ演算(lambda calculus),而且λ演算的函数可以接受函数当作输入(参数)和输出(返回值).和指令式编程相比, ...
- Python之路Python作用域、匿名函数、函数式编程、map函数、filter函数、reduce函数
Python之路Python作用域.匿名函数.函数式编程.map函数.filter函数.reduce函数 一.作用域 return 可以返回任意值例子 def test1(): print(" ...
- 跟着ALEX 学python day3集合 文件操作 函数和函数式编程 内置函数
声明 : 文档内容学习于 http://www.cnblogs.com/xiaozhiqi/ 一. 集合 集合是一个无序的,不重复的数据组合,主要作用如下 1.去重 把一个列表变成集合 ,就自动去重 ...
随机推荐
- python Django编写登录项目
Django 目录结构: __init__.py 文件: import pymysql pymysql.install_as_MySQLdb() 注意:如果 import pymysql 的时候报红, ...
- 20145122 《Java程序设计》第8周学习总结
教材学习内容总结 1.NIO使用频道(channel)来衔接数据节点,对数据区的标记提供了clear(),rewind(),flip(),compact()等高级操作. 2.想要取得channel的操 ...
- ["1", "2", "3"].map(parseInt) 为何返回[1,NaN,NaN]
转载自:http://blog.csdn.net/freshlover/article/details/19034079 这涉及到是否深入理解两个函数的格式与参数含义. 首先根据我对两个函数用法的了解 ...
- IDEA Java开发常用插件
这里只是推荐一下好用的插件,具体的使用方法就不一一详细介绍了. JRebel for IntelliJ 一款热部署插件,只要不是修改了项目的配置文件,用它都可以实现热部署.收费的,破解比较麻烦.不过功 ...
- BZOJ5293: [Bjoi2018]求和 树上差分
Description master 对树上的求和非常感兴趣.他生成了一棵有根树,并且希望多次询问这棵树上一段路径上所有节点深度的k 次方和,而且每次的k 可能是不同的.此处节点深度的定义是这个节点 ...
- Vim打开文件中文乱码如何解决?
今天想找一下之前的随机数组demo复习,在源文件src里用vim打开.java文件,中文出现乱码 vim也是,选项里没有直接选择设置utf-8之类的 查了下网上,http://easwy.com/bl ...
- Unity3D学习笔记(二):个体层次、绝对和局部坐标、V3平移旋转
Directional Light:平行光源/方向性光源,用来模拟太阳光(角度只与旋转角度有关,与位置无关) Point Light:点光源,用来模拟灯泡,向四周发散光源 Spotlight:锥光源/ ...
- C# asp.net 比较两个时间的差求天数
string str1 = "2017-2-13 23:59:59"; string str2 = "2017-2-14 0:00:01"; DateTime ...
- samtools一些文档
https://github.com/samtools/hts-specs
- Jmeter 处理Unicode编码转为中文
对于接口中返回报文,有的接口返回信息是Unicode编码,写断言的时候,要么就Response Assertion就写成Unicode编码的断言,如下图: 真心不觉得返回报文加密能有多安全,别人将报文 ...