I'm reading Eloquent Javascript and I am a little confused by this partial function example. Please help explain

Deadly 提交于 2019-12-07 05:06:33

问题


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

Why can't the function compose simply return:

func1(func2);

and give the proper output. I thought the partial function which is stored in the variable isUndefined already returns func.apply(null, [fixed, arguments])

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

回答1:


Both partial and compose are higher-order functions.

isUndefined will return a function that, when invoked, will invoke the originally passed function with the original arguments plus any new arguments passed at invocation.

To answer your question, you'd be calling apply on the function returned from partial which will in turn, call apply on the function originally passed to partial.

You want compose to return a function that when called, will return the result of calling the first function passed the second function as an argument (with the second function passed the arguments passed to the compose invocation). If compose returned func1(func2), then you'd assign the result of the invocation to the variable isDefined.

EDIT:

Now that we have op, let's try to decompose this:

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

this is equivalent to

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

isUndefined is assigned a function that, when called, will call the function passed as the first argument to partial, passing in undefined as the first argument to that function call, followed by the arguments passed to the function isUndefined i.e.

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 composes isUndefined with another function that negates the result of isUndefined.

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

is equivalent to

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

which is equivalent to (renamed variables for clarity)

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

If we look at what we have so far and substituting for readability, boils down to a function that takes an argument and compares it to undefined, negates the result and returns a boolean

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



回答2:


So lets simply dissect it. Assuming we have this compose function:

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

What will happen when you use it like this?

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

The second function would be call immediately outputting 2, and straight afterwards the first function will be called outputting 1. a will be undefined, because the first function does not return anything.

What you want combine to do, is to return a new function, that combines the two other functions and that you can call at will.

Doing the above all on the original compose, will return a new function, that, when you call it with a() will output 2 and then 1.



来源:https://stackoverflow.com/questions/8100354/im-reading-eloquent-javascript-and-i-am-a-little-confused-by-this-partial-funct

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!