反科里化的简单推导

31 Oct 2013

反科里化 (uncurrying) 是非常有趣的一个概念。

让我们像推导数学公式一样推导一下 JavaScript 里的反科里化:

  foo.bar(a, b, c)

= bar.call(foo, a, b, c)

= (Function.call).call(bar, foo, a, b, c)

= (Function.call).call(Function.call, bar, foo, a, b, c)

= (Function.call).apply(Function.call, [bar, foo, a, b, c])

用推导的结果可以写出一个有趣的函数:

var call = Function.call;
var slice = Array.prototype.slice;

function factory() {
    var defaults = slice.call(arguments);

    return function() {
        return call.apply(call, defaults.concat(slice.call(arguments)));
    };
}

这样可以很方便的实现 uncurrying

var arr = [1, 2];
fn = factory([].push);
fn(arr, 3, 4) // -> [1, 2, 3, 4]

再绑定作用域

fn = factory([].push, arr);
fn(3, 4) // -> [1, 2, 3, 4]

再加上一些默认参数

fn = factory([].push, arr, 3);
fn(4) // -> [1, 2, 3, 4]
comments powered by Disqus