這篇文章將為大家詳細講解有關JavaScript函數柯里化有什么用,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
函數柯里化
與函數綁定緊密相關的主題是函數柯里化(function currying),它用于創建已經設置好了一個或多個參數的函數。函數柯里化的基本方法和函數綁定是一樣的:使用一個閉包返回一個函數。兩者的區別在于,當函數被調用時,返回的函數還需要設置一些傳入的參數。
function add(num1, num2) {
return num1 + num2;
}
function curriedAdd(num2) {
return add(5, num2);
}
console.log(add(2, 3)); //5
console.log(curriedAdd(3));//8這段代碼定義了兩個函數:add()和curriedAdd()。后者本質上是在任何情況下第一個參數為5的add()版本。盡管從技術來說curriedAdd()并非柯里化的函數,但它很好地展示了其概念。
柯里化函數通常由以下步驟動態創建:調用另一個函數并為它傳入要柯里化的函數和必要參數。
下面是創建柯里化函數的通用方式:
function curry(fn) {
var args = Array.prototype.slice.call(arguments, 1);
return function() {
var innerArgs = Array.prototype.slice.call(arguments),
finalArgs = args.concat(innerArgs);
return fn.apply(null, finalArgs);
};
}curry()函數的主要工作就是將被返回函數的參數進行排序。curry()的第一個參數是要進行柯里化的函數,其他參數是要傳入的值。
為了獲取第一個參數之后的所有參數,在arguments對象上調用了slice()方法,并傳入參數1表示被返回的數組包含從第二個參數開始的所有參數。然后args數組包含了來自外部函數的參數。在內部函數中,創建了innerArgs數組用來存放所有傳入的參數(又一次用到了slice())。
有了存放來自外部函數和內部函數的參數數組后,就可以使用concat()方法將它們組合為finalArgs,然后使用apply()將結果傳遞給函數。注意這個函數并沒有考慮到執行環境,所以調用apply()時第一個參數是null。curry()函數可以按以下方式應用。
function add(num1, num2) {
return num1 + num2;
}
var curriedAdd = curry(add, 5);
alert(curriedAdd(3)); //8在這個例子中,創建了第一個參數綁定為5的add()的柯里化版本。當調用cuurriedAdd()并傳入3時,3會成為add()的第二個參數,同時第一個參數依然是5,最后結果便是和8。也可以像下例這樣給出所有的函數參數:
function add(num1, num2) {
return num1 + num2;
}
var curriedAdd2 = curry(add, 5, 12);
alert(curriedAdd2()); //17在這里,柯里化的add()函數兩個參數都提供了,所以以后就無需再傳遞給它們了,函數柯里化還常常作為函數綁定的一部分包含在其中,構造出更為復雜的bind()函數。
function bind(fn, context) {
var args = Array.prototype.slice.call(arguments, 2);
return function() {
var innerArgs = Array.prototype.slice.call(arguments),
finalArgs = args.concat(innerArgs);
return fn.apply(context, finalArgs);
};
}對curry()函數的主要更改在于傳入的參數個數,以及它如何影響代碼的結果。curry()僅僅接受一個要包裹的函數作為參數,而bind()同時接受函數和一個object對象。
這表示給被綁定的函數的參數是從第三個開始而不是第二個,這就要更改slice()的第一處調用。另一處更改是在倒數第3行將object對象傳給apply()。當使用bind()時,它會返回綁定到給定環境的函數,并且可能它其中某些函數參數已經被設好。
要想除了event對象再額外給事件處理程序傳遞參數時,這非常有用。
var handler = {
message: "Event handled",
handleClick: function(name, event){
alert(this.message + ":" + name + ":" + event.type);
}
};var btn = document.getElementById("my-btn");
EventUtil.addHandler(btn, "click", bind(handler.handleClick, handler, "my-btn"));handler.handleClick()方法接受了兩個參數:要處理的元素的名字和event對象。作為第三個參數傳遞給bind()函數的名字,又被傳遞給了handler.handleClick(),而handler.handleClick()也會同時接收到event對象。
ECMAScript5的bind()方法也實現函數柯里化,只要在this的值之后再傳入另一個參數即可。
var handler = {
message: "Event handled",
handleClick: function(name, event) {
alert(this.message + ":" + name + ":" + event.type);
}
};
var btn = document.getElementById("my-btn");
EventUtil.addHandler(btn, "click", handler.handleClick.bind(handler, "my-btn"));javaScript中的柯里化函數和綁定函數提供了強大的動態函數創建功能。使用bind()還是curry()要根據是否需要object對象響應來決定。它們都能用于創建復雜的算法和功能,當然兩者都不應濫用,因為每個函數都會帶來額外的開銷。
關于“JavaScript函數柯里化有什么用”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。