2011-11-11 22 views
5
function asArray(quasiArray, start) { 
    var result = []; 
    for (var i = (start || 0); i < quasiArray.length; i++) 
    result.push(quasiArray[i]); 
    return result; 
} 

function partial(func) { 
    var fixedArgs = asArray(arguments, 1); 
    return function(){ 
    return func.apply(null, fixedArgs.concat(asArray(arguments))); 
    }; 
} 

function compose(func1, func2) { 
    return function() { 
    return func1(func2.apply(null, arguments)); 
    }; 
} 

var isUndefined = partial(op["==="], undefined); 
var isDefined = compose(op["!"], isUndefined); 
show(isDefined(Math.PI)); 
show(isDefined(Math.PIE)); 

爲什麼不能在功能譜曲簡單的返回:我正在閱讀Eloquent Javascript,我對這個部分函數示例有點困惑。請幫忙解釋一下

func1(func2); 

,並給予適當的輸出。我認爲其被存儲在所述可變isUndefined已經返回func.apply的部分功能(NULL,[固定,參數])

var op = { 
"+": function(a, b){return a + b;}, 
"==": function(a, b){return a == b;}, 
"===": function(a, b){return a === b;}, 
"!": function(a){return !a;} 
/* and so on */ 
}; 
+0

「op」在哪裏申報?你可以加入嗎? –

+0

哎呀對不起 – Shaan

回答

2

partialcompose都是higher-order functions

isUndefined將返回一個函數,該函數在調用時將調用原始傳遞函數以及原始參數加上調用時傳遞的任何新參數。

要回答你的問題,你可以致電applypartial返回的函數,然後調用apply函數原來傳遞給partial

想要compose返回一個函數,當調用該函數時,將返回調用傳遞第二個函數作爲參數的第一個函數的結果(第二個函數傳遞傳遞給compose調用的參數)。如果compose返回func1(func2),那麼您會將調用的結果分配給變量isDefined

編輯:

現在,我們有op,讓我們嘗試分解如下:

var isUndefined = partial(op["==="], undefined); 

這相當於

var isUndefined = partial(function(a, b){return a === b;}, undefined); 

isUndefined分配的功能,當調用將作爲第一個參數傳遞給partial的函數,傳遞i Ñundefined作爲第一個參數,以該函數調用,隨後傳遞給函數isUndefined

partial(function(a, b){return a === b;}, undefined /* this will become 'a' when isUndefined is invoked */)(argumentForisUndefined /* this will become 'b' when isUndefined is invoked */); 

isDefined參數構成isUndefined與否定的isUndefined結果另一功能。

var isDefined = compose(op["!"], isUndefined); 

相當於

var isDefined = compose(function(a){return !a;}, isUndefined); 

這相當於(爲清楚起見改名變量)

var isDefined = compose(

    function(a){return !a;}, 

    partial( /* partial function becomes 'a' passed to first function */ 
     function(b, c) { 
      return b === c; 
     }, 
     undefined /* undefined becomes 'b' passed to partial */ 
    ) 

)(argumentForisDefined /* argumentForisDefined becomes 'c' passed to partial */); 

如果我們看一下,我們有這麼遠,替代可讀性,歸結轉換爲接受參數並將其與未定義的函數進行比較,否定結果並返回布爾型

var isDefined = function (b) { return !undefined === b; } 
+0

好吧我想我明白我自己的困惑。我很困惑爲什麼function.apply出現兩次。但是,如果Compose函數只是func1(func2),則參數(在本例中爲Math.PI或Math.PIE)永遠不會傳遞給部分函數。我對嗎? – Shaan

+0

這是正確的 - 撰寫不會返回它最初傳遞的兩個函數的函數組合,但會返回立即調用它們的結果,所以不會將任何附加值傳遞給「partial」。它會被調用。 –

0

所以讓簡單地解剖它。假設我們有這個組合功能:

function compose(func1, func2) { 
    return func1(func2.apply(null, arguments)); 
} 

當你這樣使用它時會發生什麼?

a = compose(function(){console.log(1)}, function(){console.log(2)}); 

第二個函數會被立即調用輸出2,而直後的第一個函數將被調用輸出1a將爲undefined,因爲第一個函數不會返回任何內容。

你想結合做什麼,是返回一個新的功能,它結合了其他兩個功能,你可以隨意調用。

完成上述所有原始撰寫後,將返回一個新功能,即,當您撥打a()時,將輸出2,然後輸出1