前言
最近是想着坚实一下自己JS的基础,所以想着看看原生的知识。
准备
在这里先说说什么是函数柯里化。
- 什么是函数柯里化
在一个函数中首先填充几个参数(然后再返回一个新函数)的技术称为柯里化(Currying)。(来自《JavaScript忍者秘籍》一书中)
开始
这里有两个例子可以帮助理解!
最简单的加法函数1
2
3
4
5
6//函数定义
function add(x,y){
return x + y;
}
//函数调用
add(3,4);//5
如果采用柯里化是怎样将接受两个参数的函数变成接受单一参数的函数呢,其实很简单如下:1
2
3
4
5
6
7
8//函数表达式定义
var add = function(x){
return function(y){
return x + y;
}
};
//函数调用
add(3)(4);
其实实质利用的就是闭包的概念。
作用
本质上讲柯里化(Currying)只是一个理论模型,柯里化所要表达是:如果你固定某些参数,你将得到接受余下参数的一个函数,所以对于有两个变量的函数y^x
,如果固定了y=2
,则得到有一个变量的函数2^x
。这就是求值策略中的部分求值策略。
柯里化(Currying)具有:延迟计算、参数复用、动态生成函数的作用。
JS中bind()与函数柯里化
其实在实际使用中使用最多的一个柯里化的例子就是Function.prototype.bind()
函数,我们也一并给出一个较为简单的Function.prototype.bind()
函数的实现方式。
1 | //《JS权威指南》原文的例子 |
实战演练一道关于闭包和函数的柯里化方面的编程题目
编程题目的要求如下,完成plus函数,通过全部的测试用例。
1
2
3
4
5'use strict';
function plus(n){
}
module.exports = plus
测试用例如下
1 | 'use strict'; |
根据测试用例我们可以发现,plus函数的要求就是接受单一函数,例如:
1
plus(1)(4)(2)(3).toString()
但是与柯里化不同之处在于,柯里化返回的一个新函数。我们观察其实最后的求值是通过toString函数得到的,那么我们就很容易想到,我们可以给返回的函数增加一个toString属性就可以了。答案如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22'use strict';
function plus(num) {
var adder = function () {
var _args = [];
var _adder = function _adder() {
[].push.apply(_args, [].slice.call(arguments));
return _adder;
};
_adder.toString = function () {
return _args.reduce(function (a, b) {
return a + b;
});
}
return _adder;
}
return adder()(num);
}
module.exports = plus;
运行一下,通过全部的测试用例,需要注意的是由于题目的要求运行在严格模式下,所以我们在_adder函数内部是不能引用arguments.callee,这时我们采用的方法是给函数表达式中函数本身起名_adder,这样就解决的这个问题。