柯里化就是將一個(gè)接收“多個(gè)”參數(shù)的函數(shù)拆分成一個(gè)或者許多個(gè)接收“單一”參數(shù)的函數(shù)。
特點(diǎn):
- 固定易變因素
- 延遲計(jì)算
- 提前綁定好函數(shù)里面的某些參數(shù),達(dá)到參數(shù)復(fù)用的效果,提高了適用性
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);//默認(rèn)去掉第一個(gè)數(shù)
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
柯里化的應(yīng)用##
延遲執(zhí)行
function hello(name) {
console.log('Hello, ' + name);
}
setTimeout(hello('dreamapple'), 3600); //立即執(zhí)行,不會(huì)在3.6s后執(zhí)行
setTimeout(function() {
hello('dreamapple');
}, 3600); // 3.6s 后執(zhí)行
然,在ES5里面,我們也可以使用函數(shù)的bind
方法,如下所示:
setTimeout(hello.bind(this, 'dreamapple'), 3600); // 3.6s 之后執(zhí)行函數(shù)
我們本篇文章是討論函數(shù)的柯里化,當(dāng)然我們這里也可以使用函數(shù)的柯里化來(lái)達(dá)到這個(gè)效果:
setTimeout(curryingHelper(hello, 'dreamapple'), 3600); // 其中curryingHelper是上面已經(jīng)提及過(guò)的
高階函數(shù)(high-order function)##
高階函數(shù)就是操作函數(shù)的函數(shù),它接受一個(gè)或多個(gè)函數(shù)作為參數(shù),并返回一個(gè)新的函數(shù).
我們來(lái)看一個(gè)例子,來(lái)幫助我們理解這個(gè)概念.就舉一個(gè)我們高中經(jīng)常遇到的場(chǎng)景,如下:
f1(x, y) = x + y;
f2(x) = x * x;
f3 = f2(f3(x, y));
我們來(lái)實(shí)現(xiàn)f3函數(shù),看看應(yīng)該如何實(shí)現(xiàn),具體的代碼如下所示:
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
性能###
柯里化肯定會(huì)有一些開銷(函數(shù)嵌套,比普通函數(shù)占更多內(nèi)存),但性能瓶頸首先來(lái)自其它原因(DOM 操作等)。
從另外一個(gè)角度分析,不管你用不用柯里化這個(gè)思維,你的代碼很可能已經(jīng)步入了更復(fù)雜的模式,會(huì)有更大的開銷。
Function.prototype.toString()##
該 toString() 方法返回一個(gè)表示當(dāng)前函數(shù)源代碼的字符串。
Number.prototype.valueOf()##
該方法通常是由 JavaScript 引擎在內(nèi)部隱式調(diào)用的,而不是由用戶在代碼中顯式調(diào)用的。
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