JavaScript的bind()与currying。这些代码如何工作?

时间:2016-03-06 07:44:06

标签: javascript functional-programming

这些代码两天前发布在CodeReview上:

function curry(f, self) {
  return function () {
    if (arguments.length == f.length) {
      return f.apply(self, arguments);
    }
    arguments = Array.prototype.slice.call(arguments);

    return curry(f.bind.apply(f, [self].concat(arguments)));
  }
}

function f(a, b, c, d) {
  return this + a + b + c + d;
}

document.write("f(1, 2, 3, 4) = ", curry(f, 0)(1, 2, 3, 4), "<br>");
document.write("f(1, 2, 3)(4) = ", curry(f, 0)(1, 2, 3)(4), "<br>");
document.write("f(1)(2, 3, 4) = ", curry(f, 0)(1)(2, 3, 4), "<br>");
document.write("f(1)(2)(3)(4) = ", curry(f, 0)(1)(2)(3)(4), "<br>");

我无法理解的是:

使用bind()创建了f的新副本。已经提供的参数被分配给副本,但变量“self”是什么?

我试图“勾画”我的意思:

// Second parenthesis (marked with =>): There are three of four  
// expected parameter provided: 
document.write("f(1, 2, 3)(4) = ", curry(f, 0) => (1, 2, 3) <= (4), "<br>");

// Makes an array-literal with "self" (== 0) as only element in it.
// Then adds the parameter already provided to these array by
// using concat(). => Results in an array [ 0, 1, 2, 3 ].
// Then makes a new copy of f with these values bind to it as parameter. 
// These new instance of the function is then passed to the curry-function.
return curry(f.bind.apply(f, [self].concat(arguments)));

f的副本应该有它的四个参数。它应该被执行并导致“返回0 + 0 + 1 + 2 + 3;”并返回6.

为什么不是这种情况?

也许有人可以回答这个问题。我会很感激。

1 个答案:

答案 0 :(得分:2)

  

变量“self”是什么?它用于覆盖this-keyword,并且已添加到赋予函数的数组中。

不,不是:

  f.bind.apply(f, [self].concat(arguments))
≡ f.bind.apply(f, [self].concat([1, 2, 3]))
≡ f.bind.apply(f, [0, 1, 2, 3])
≡ f.bind(0, 1, 2, 3)

self / 0绑定为this参数,123绑定为三个部分应用的参数。这里没有重复的东西。结果是一个函数

function bound_f(x, ...args)
    return f.call(0, 1, 2, 3, x, ...args);
}

然后再次进行curry,可以使用4作为参数调用。