函式柯里化 - 函式鏈式呼叫 - lazyman
阿新 • • 發佈:2018-11-03
實現鏈式呼叫實現 add函式,add(1)(2)(3)(4)輸出10,然後考慮拓展性
// 解析為add(1)返回函式A,A(2)返回函式B, B(3)返回函式C
function add(num) {
var sum = 0;
sum += num;
return function(a) {
sum += a;
return functin(b) {
sum += b;
return function(c) {
sum += c;
return sum;
}
}
}
}
但是如果鏈式呼叫加長,這種方法顯然不能滿足需求
// 改進
function add(num) {
var sum = 0;
sum += num;
var func = function(param) {
sum += param;
return func;
}
return func;
}
// 這樣呼叫的結果返回的是一個函式的字串表示,那麼怎樣將結果輸出呢?
js中物件到原始值的轉換有兩種方法
當一個物件轉為原始值時,先檢視物件是否有valueOf方法,如果有且返回值為一個原始值,則直接返回該原始值,否則呼叫toString方法,返回字串表示
// 輸出數字型別的結果
function add(num) {
var sum = 0;
sum += num;
var func = function(a) {
sum += a;
return func;
}
func.valueOf = function() { // 函式結果輸出
return sum;
}
func.toString = function() {
return sum;
}
return func;
}
函式鏈式呼叫
實現函式的鏈式呼叫:util.chain(1).add(2).sum(3);
class utils {
chain(a) {
this.val = a;
return this;
}
sum(b) {
this.val += b;
return this;
}
sub(c) {
this.val -= c;
return this;
}
value() {
return this.val;
}
}
var util = new utils();
實現lazyman
// lazyMan類的封裝
function _LazyMan(name) {
this.taskList = []; // 順序執行佇列
var self = this;
var fn = (function(n){
var name = name;
return function() {
console.log('Hi! This is ' + name + '!');
self.next();
}
})(name);
this.taskList.push(fn);
setTimeout(function(){
self.next();
}, 0); // 延遲執行函式
}
_LazyMan.prototype.next = function() {
var fn = this.taskList.shift(); // 獲取第一個函式執行
fn && fn();
}
_LazyMan.prototype.eat = function(name) {
var self = this;
var fn = (function(n){
return function() {
console.log('Eat ' + name + '~');
self.next(); // 鏈式呼叫,啟動下一個函式的執行
}
})(name);
this.taskList.push(fn);
return this; // 實現鏈式呼叫
}
_LazyMan.prototype.sleep = function(time) {
var self = this;
var fn = (function(time){
return function() {
setTimeout(function() {
console.log('Wake up after ' + time + 's!');
self.next();
}, time * 1000);
})(time);
this.taskList.push(fn);
return this;
}
_LazyMan.prototype.sleepFirst = function(time) {
var self = this;
var fn = (function(time){
return function() {
setTimeout(function() {
console.log('Wake up after ' + time + 's!');
self.next();
}, time * 1000);
})(time);
this.taskList.unshift(fn);
return this;
}
// 最後的封裝
function LazyMan(name) {
return new _LazyMan(name);
}