javascript - 部分应用 - Eloquent Javascript

标签 javascript partial-application

我正在阅读 Eloquent Javascript 并且很难理解下面的示例。谁能逐行解释?具体来说,我很困惑为什么第一个循环从一个开始,以及为什么 push 方法同时用于 knownArgs 和参数。我知道这与“部分应用”有关,但想要逐行更详细地解释到底发生了什么。

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("如何", "是", "你");

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

edit — 如何逐步分解 map(partial(op["+"], 1), [0, 2, 4, 6, 8, 10]);被评估:

  1. 首先,op["+"]必须进行评估。我猜它会返回一个函数,可能是这样的:

    function add(a, b) {
      return a + b;
    }
    
  2. “添加”函数和值 1传递给 partial() .因此里面 partial() arguments伪数组看起来像

    [ add, 1 ]
    

    也就是说,第一个参数是来自op["+"]的“添加”函数第二个是值 1 .唯一partial()返回匿名函数之前真正做的是保存arguments进入knownArgs .必须这样做,因为奇怪的 arguments伪变量总是在每次函数调用时分配一个新值。它被保留在这里,以便匿名函数中的代码以后可以访问它。

  3. 现在,使用从 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()函数只传递一个参数,因此每次调用匿名函数时生成的参数列表的值都是1。传递给 partial()然后,在每次迭代中,从列表中选择一个不同的偶数。

一个更简单的例子是考虑调用时会发生什么:

partial(op["+"], 1)(2);

也就是说,如果您调用 partial()然后立即使用它的返回值(匿名函数)。效果将与调用相同:

add(1, 2);

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

相关文章:

javascript - 创建具有更改字段的函数(Javascript?)

clojure - Clojure 中的 reader monad 和偏函数有什么区别?

rust - Rust中的部分应用程序宏可以工作,但是

haskell - 为什么部分应用程序 `foldr id` 会进行类型检查?

c++ - 函数模板、部分应用和模板参数推导

javascript - NEXT.js 同构-unfetch 出错

javascript - 具有速记赋值的后增量运算符

javascript - d3.js - 时间尺度上均匀分布的条形

javascript - 修改闭包编译器的内置 extern

JavaScript curry 函数