一、函式柯里化
currying :是把接受多個引數的函式變換成接受乙個單一引數(最初函式的第乙個引數)的函式,並且返回接受餘下的引數而且返回結果的新函式的技術。
例:記錄程式設計師乙個月的加班總時間,那麼好,我們首先要做的是記錄程式設計師每天加班的時間,然後把乙個月中每天的加班的時間相加,就得到了乙個月的加班總時間。
var monthtime = 0;
function overtime(time)
overtime(3.5); // 第一天
overtime(4.5); // 第二天
overtime(2.1); // 第三天
//...
console.log(monthtime); // 10.1
下面的overtime函式還不是乙個柯里化函式的完整實現,但可以幫助我們了解其核心思想:
var overtime = (function()
return time;
}else
}})();
overtime(3.5); // 第一天
overtime(4.5); // 第二天
overtime(2.1); // 第三天
//...
console.log( overtime() ); // 10.1
例:使用currying與不使用進行對比
// 普通的add函式
function add(x, y)
// currying後
function curryingadd(x)
}add(1, 2) // 3
curryingadd(1)(2) // 3
使用currying的好處
(1)引數復用
/*正常正則驗證字串 reg.test(txt)*/
// 函式封裝後
function check(reg, txt)
console.log(check(/\d+/g, 'test')); //false
console.log(check(/[a-z]+/g, 'test')); //true
// currying後
function curryingcheck(reg)
}var hasnumber = curryingcheck(/\d+/g);
var hasletter = curryingcheck(/[a-z]+/g);
console.log(hasnumber('test1')); // true
console.log(hasnumber('testtest')); // false
console.log(hasletter('21212')); // false
(2)提前確認
//第一種:最常見封裝dom的方法
var on = function(element, event, handler)
} else
}}//第二種:相對於第一種來說,就是自執行然後返回乙個新的函式,這樣其實就是提前確定了會走哪乙個方法,避免每次都進行判斷
var on = (function()
};}
else };}
})();
//第三種:把issupport這個引數給先確定下來了
var on = function(issupport, element, event, handler)
else
}
(3)延遲執行
js中經常使用的bind,實現的機制就是currying:
function.prototype.bind=function(context)
};
通用的封裝方式:
// 初步封裝
var currying = function(fn)
}//使用方式
function add(num1,num2)
var curriedadd=currying(add,5);
console.log(curriedadd(8)); //40
多引數的封裝:
// 支援多引數傳遞
function progresscurrying(fn, args)
}}
curry的效能
練習題
function add() ;
// 利用tostring隱式轉換的特性,當最後執行時隱式轉換,並計算最終的值返回
adder.tostring = function () );
};return adder;
}console.log(add(1)(2)(3)); //6
console.log(add(1,2,3)(4)); // 10
console.log(add(1)(2)(3)(4)(5)); // 15
console.log(add(2,6)(1)); // 9
二、函式反柯里化
當我們呼叫物件的某個方法時,不用去關心該物件原本是否被設計為擁有這個方法,只要這個方法適用於它,我們就可以對這個物件使用它。
例:使用uncurrying將泛化this的過程提取出來
//分析一下呼叫array.prototype.push.uncurring()這句**時,發生了什麼事情:
function.prototype.uncurring = function()
//arguments的第乙個物件被截去(也就是呼叫push方法的物件),剩下[2]
};};//測試一下
var push = array.prototype.push.uncurring();
var obj = ;
push(obj, 2);
console.log( obj ); //
另一種實現方式:
function.prototype.uncurring=function()
};
例:把array.prototype.push方法轉換成乙個通用的push函式
var push = array.prototype.push.uncurring();
//測試一下
//arguments本來是沒有push方法的,通常,我們都需要用array.prototype.push.call來實現push方法,但現在,直接呼叫push函式,既簡潔又意圖明了。
(function() )(1, 2, 3);
柯里化與反柯里化
柯里化,可以理解為提前接收部分引數,延遲執行,不立即輸出結果,而是返回乙個接受剩餘引數的函式。因為這樣的特性,也被稱為部分計算函式。柯里化,是乙個逐步接收引數的過程。在接下來的剖析中,你會深刻體會到這一點。反柯里化,是乙個泛型化的過程。它使得被反柯里化的函式,可以接收更多引數。目的是建立乙個更普適性...
柯里化與反柯里化
柯里化,可以理解為提前接收部分引數,延遲執行,不立即輸出結果,而是返回乙個接受剩餘引數的函式。因為這樣的特性,也被稱為部分計算函式。柯里化,是乙個逐步接收引數的過程。在接下來的剖析中,你會深刻體會到這一點。反柯里化,是乙個泛型化的過程。它使得被反柯里化的函式,可以接收更多引數。目的是建立乙個更普適性...
反柯里化函式
反柯里化 function.prototype.uncurry function 實際使用 1.當用object.prototype.tostring校驗物件型別時 獲取校驗方法 let tostring object.prototype.tostring.uncurry 測試物件資料型別 cons...