我正在阅读Eloquent Javascript,并且很难理解下面的示例。有人可以逐行进行解释吗?具体来说,我对为什么第一个循环从一个循环开始以及为什么在已知的参数和参数上同时使用push方法感到困惑。我知道这与“部分应用程序”有关,但是想对逐行发生的情况进行更详细的说明。

var op = {
 "+": function(a,b){return a + b;}
};

function partial(func) {
 var knownArgs = arguments;

 return function() {
  var realArgs = [];

  for (var i=1; i<knownArgs.length; i++)
   realArgs.push(knownArgs[i]);

  for (var i=0; i<arguments.length; i++)
   realArgs.push(arguments[i]);

  return func.apply(null, realArgs);
 };
}

map(partial(op["+"], 1), [0, 2, 4, 6, 8, 10]);

最佳答案

knownArgs变量保留arguments值的副本,就像调用partial()时一样。该调用返回了另一个函数,在该代码arguments中是一个完全不同的列表-它们是传递给该返回函数的参数。换一种说法:

var p = partial(someFunction,“hello”,“world”);

调用p()时,knownArgs将为“hello”和“world”(也包括someFunction,但请注意,第一个循环从1开始)。如果对p()的调用如下所示:

p(“如何”,"is",“你”);

然后它将首先将“hello”和“world”推送到realArgs列表(来自knownArgs),然后将三个参数从p()传递到arguments

编辑-逐步评估map(partial(op["+"], 1), [0, 2, 4, 6, 8, 10]);的方式:

  • 首先,必须评估op["+"]。我猜它返回一个函数,可能是这样的:
    function add(a, b) {
      return a + b;
    }
    
  • 会将“add”函数和值1传递给partial()。因此在partial()中,arguments伪数组看起来像
    [ add, 1 ]
    

    也就是说,第一个参数是op["+"]中的“add”函数,第二个参数是该值1partial()在返回匿名函数之前真正要做的唯一一件事就是将arguments保存到knownArgs中。这样做是因为奇怪的arguments伪变量始终在每个函数调用时分配一个新值。它被保留在这里,以便匿名函数中的代码可以在以后访问它。
  • 现在,有了从partial()返回的匿名函数和偶数数组,我们将其称为map()。该函数可能看起来像这样(我没有书):
    function map(fn, list) {
      var i, result = [];
      for (i = 0; i < list.length; ++i) {
        result.push( fn( list[i] ) );
      }
      return result;
    }
    

    然后,在map()内部,第一个参数是从较早调用partial()返回的匿名函数。该功能有什么作用?好吧,它将原始partial()调用中的参数(第一个除外)与传递给它的参数结合在一起。 map()函数仅传递一个参数,因此,对匿名函数的每次调用所得到的参数列表将是传递给1partial()值,然后在每次迭代时,将使用与列表不同的偶数。

  • 一个简单的示例是考虑调用时发生的情况:
    partial(op["+"], 1)(2);
    

    也就是说,如果您调用partial(),然后立即使用其返回值(匿名函数)。效果与调用相同:
    add(1, 2);
    

    关于javascript - 部分应用- Eloquent Javascript,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13335600/

    10-10 19:38