高階函式 函式柯里化與反柯里化

2021-09-26 04:12:06 字數 3432 閱讀 8532

一、函式柯里化

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...