淺談JavaScript中的柯里化函數

  首先,不可避免的要引經據典啦,什麼是柯里化函數呢(from baidu):html

     在計算機科學中,柯里化(Currying)是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,而且返回接受餘下的參數且返回結果的新函數的技術。這個技術由 Christopher Strachey 以邏輯學家 Haskell Curry 命名的,儘管它是 Moses Schnfinkel 和 Gottlob Frege 發明的。數組

用於建立已經設置好了一個或多個參數的函數 與函數綁定類似,他們之間的區別在於:當函數被調用時,返回的函數還須要設置一些傳入的參數閉包

  
下面咱們來看看具體的代碼:
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);
            };
        }

相應的調用:app

function add(num1, num2){
            return num1 + num2;
        }
        
        var curriedAdd = curry(add, 5);
        alert(curriedAdd(3));   //8

 

   那麼,下面咱們來一步一步的解釋上面的curry函數:   首先,不要被其形式參數所迷惑,難不成就只能傳一個參數了嗎?  固然不是,js是支持可變參數的,咱們並不要求其參數形式,最終調用者傳過來的全部參數咱們均可以經過arguments來訪問,OK,咱們先來解釋第一行:函數

var args = Array.prototype.slice.call(arguments, 1);

  要讀懂這一句的前提是咱們要熟悉call函數的調用,以及Array對象的slice方法的熟悉,此處再也不累贅,讀者能夠自行去查,調用slice(1)將會返回除了第一個元素之外的後面的全部的元素的數組形式。 同時他具有將調用者直接將arguments轉換爲數組形式的能力,咱們此處是用函數的arguments去調用的slice();   官方給arguments的定義是:spa

An argument is a value (primitive or object) passed as input to a function.prototype

 

arguments 對象並非一個真正的Array。它相似於數組,但沒有數組所特有的屬性和方法,除了 length。例如,它沒有 pop 方法。不過能夠經過slice將其轉換成數組:code

此處的結果是: args = [5]     此時args保存了來自外部函數的數組htm

 

 

那麼:接下來,咱們將一個匿名函數返回給了調用者,此處造成了一個閉包, 對閉包不是很熟悉的童鞋能夠看看我以前寫過的一篇文章: http://www.cnblogs.com/Frank-C/p/4964999.html對象

將這個匿名函數返回之後呢:下一步咱們就開始調用了curriedAdd(3):咱們如今講目光轉向這個匿名函數:

return function(){
                var innerArgs = Array.prototype.slice.call(arguments),
                    finalArgs = args.concat(innerArgs);
                return fn.apply(null, finalArgs);
            };

再次調用slice,注意,讀者應該將此時的arguments和以前再匿名函數在外curry函數以內的arguments區分,他們的調用者和調用方式都不同了哦。   此處,咱們把調用方傳過來的參數轉化爲數組,—》》》innerArgs = [3]  而後:咱們鏈接兩個數組  

---》》》finalArgs = [5,3];

 

最後咱們直接調用以前傳入的函數fn(經過curry函數傳入)來時實現最終的add方法,此處沒有用call函數,而是用的apply函數,是由於關係到他們兩個之間的差異,apply的參數是能夠用數組包裹的!!!

 

   經過上面的幾步的簡單講解。咱們能夠總結:函數的柯里化其實就是在調用一個擁有多個參數的函數以前,提早傳入他們的部分參數,後期調用時就只要傳餘下的部分了!   

相關文章
相關標籤/搜索