柯里化就是将一个接收“多个”参数的函数拆分成一个或者许多个接收“单一”参数的函数。
特点:
- 固定易变因素
- 延迟计算
- 提前绑定好函数里面的某些参数,达到参数复用的效果,提高了适用性
function add(a, b) {
return a + b;
}
function curryingAdd(a) {
return function(b) {
return a + b;
}
}
add(1, 2); // 3
curryingAdd(1)(2); // 3
function curryingHelper(fn) {
var _args = Array.prototype.slice.call(arguments, 1);
return function() {
var _newArgs = Array.prototype.slice.call(arguments);//默认去掉第一个数
var _totalArgs = _args.concat(_newArgs);
return fn.apply(this, _totalArgs);
}
}
function showMsg(name, age, fruit) {
console.log('My name is ' + name + ', I\'m ' + age + ' years old, ' + ' and I like eat ' + fruit);
}
var curryingShowMsg1 = curryingHelper(showMsg, 'dreamapple');
curryingShowMsg1(22, 'apple'); // My name is dreamapple, I'm 22 years old, and I like eat apple
var curryingShowMsg2 = curryingHelper(showMsg, 'dreamapple', 20);
curryingShowMsg2('watermelon'); // My name is dreamapple, I'm 20 years old, and I like eat watermelon
柯里化的应用##
延迟执行
function hello(name) {
console.log('Hello, ' + name);
}
setTimeout(hello('dreamapple'), 3600); //立即执行,不会在3.6s后执行
setTimeout(function() {
hello('dreamapple');
}, 3600); // 3.6s 后执行
然,在ES5里面,我们也可以使用函数的bind
方法,如下所示:
setTimeout(hello.bind(this, 'dreamapple'), 3600); // 3.6s 之后执行函数
我们本篇文章是讨论函数的柯里化,当然我们这里也可以使用函数的柯里化来达到这个效果:
setTimeout(curryingHelper(hello, 'dreamapple'), 3600); // 其中curryingHelper是上面已经提及过的
高阶函数(high-order function)##
高阶函数就是操作函数的函数,它接受一个或多个函数作为参数,并返回一个新的函数.
我们来看一个例子,来帮助我们理解这个概念.就举一个我们高中经常遇到的场景,如下:
f1(x, y) = x + y;
f2(x) = x * x;
f3 = f2(f3(x, y));
我们来实现f3函数,看看应该如何实现,具体的代码如下所示:
function f1(x, y) {
return x + y;
}
function f2(x) {
return x * x;
}
function func3(func1, func2) {
return function() {
return func2.call(this, func1.apply(this, arguments));
}
}
var f3 = func3(f1, f2);
console.log(f3(2, 3)); // 25
性能###
柯里化肯定会有一些开销(函数嵌套,比普通函数占更多内存),但性能瓶颈首先来自其它原因(DOM 操作等)。
从另外一个角度分析,不管你用不用柯里化这个思维,你的代码很可能已经步入了更复杂的模式,会有更大的开销。
Function.prototype.toString()##
该 toString() 方法返回一个表示当前函数源代码的字符串。
Number.prototype.valueOf()##
该方法通常是由 JavaScript 引擎在内部隐式调用的,而不是由用户在代码中显式调用的。
var numObj = new Number(10);
console.log(typeof numObj); // object
var num = numObj.valueOf();
console.log(num); // 10
console.log(typeof num); // number
参考:https://segmentfault.com/a/1190000006096034
https://segmentfault.com/a/1190000003733107