2011-11-11 8 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)); 

¿por qué no la función devuelva composé:Estoy leyendo un JavaScript elocuente y estoy un poco confundido por este ejemplo de función parcial. Por favor, ayudar a explicar

func1(func2); 

y dar la salida adecuada. Pensé que la función parcial que se almacena en la variable isUndefined ya vuelve func.apply (nulo, [fijo, argumentos])

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

donde se declara 'op'? ¿Puedes agregar eso? –

+0

Vaya, sí lo siento – Shaan

Respuesta

2

Tanto partial y compose son higher-order functions.

isUndefined devolverá una función que, cuando se invoca, invocará la función aprobada originalmente con los argumentos originales más cualquier argumento nuevo pasado en la invocación.

Para responder a su pregunta, estaría llamando apply en la función de regresar de partial que a su vez, llama apply en la función pasada originalmente para partial.

¿Quieres compose para devolver una función que cuando se le llama, devolverá el resultado de llamar a la primera función pasada la segunda función como argumento (con la segunda función pasada los argumentos que se pasan a la compose invocación). Si compose devolviera func1(func2), asignaría el resultado de la invocación a la variable isDefined.

EDIT:

Ahora que tenemos op, vamos a tratar de descomponer esto:

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

esto es equivalente a

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

isUndefined se le asigna una función que, cuando llamada, llamará a la función pasada como el primer argumento a partial, pasando i n undefined como el primer argumento de dicha llamada de función, seguido por los argumentos pasados ​​a la función isUndefined es decir

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 compone isUndefined con otra función que niega el resultado de isUndefined.

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

es equivalente a

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

lo que equivale a (variables cambiado el nombre por motivos de claridad)

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 */); 

Si nos fijamos en lo que tenemos hasta ahora y sustituyendo para facilitar la lectura, se reduce a una función que toma un argumento y lo compara con indefinido, niega el resultado y devuelve un booleano

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

Bien, creo que entiendo mi propia confusión. Estaba confundido sobre por qué function.apply aparecía dos veces. Pero si la función Compose fuera solo func1 (func2), los argumentos (en este caso, Math.PI o Math.PIE) nunca pasarían a la función parcial. ¿Estoy en lo cierto? – Shaan

+0

Correcto: compose no devolvería una composición de funciones de las dos funciones que se aprobó originalmente, pero devolvería el resultado de llamarlas inmediatamente, por lo que no habría ningún modo de pasar valores adicionales a 'partial'; ya habría sido llamado. –

0

por lo que permite simplemente analizarlo. Suponiendo que tengamos esta función de composición:

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

¿Qué pasará cuando lo use así?

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

La segunda función se llama inmediatamente la salida de 2, y recto después de la primera función será llamada la salida 1. a será undefined, porque la primera función no devuelve nada.

Lo que quiere combinar para hacer, es devolver una nueva función, que combina las otras dos funciones y que puede llamar a voluntad.

Haciendo todo lo anterior en la composición original, se devolverá una nueva función, que, cuando la llame con a() dará salida a 2 y luego a 1.

Cuestiones relacionadas