在不使用 javascript 中的闭包的情况下传递给函数之前转换参数

Transform argument before passing to a function without use of a closure in javascript

有时我发现自己在节点中有以下模式。

var foobar = function(x, y) {
  foo(x, bar(y));
};

您可以想象,您可能会将此模式视为匿名闭包,在对结果执行转换 bar 后调用回调函数 foo

... , function(err, result) {
    callback(err, transform(result));
} ...

我的问题;有没有办法以优雅的方式简化这种模式?理想情况下,它不需要新的实用函数(如下所示)即可工作,而是利用下划线(或类似的)。


尝试的解决方案

foobar 的组合很接近(这让我想到下划线的 _.compose 的变体),但转换后的值只是传递给的参数之一foo.

我的不雅解决方案需要一个新的效用函数(并且可能不适用于非原始参数)是:

function partialCompose(func, transform, position) {
    var args = Array.prototype.slice.call(arguments, 3);
    args[position] = transform(args[position]);
    return func.apply(this, args);
}

//usage
var foobar = partialCompose.bind(this, foo, bar, 1)

我个人认为这在清晰度方面比原始模式差。任何人都可以对此进行改进吗?感觉应该比较简单,我漏掉了一些明显的东西。

我最近找到了图书馆 Ramda:

A practical functional library for Javascript programmers.

我的早期印象似乎是它试图扩展和改进 underscore 和 lodash 等库,同时更严格地坚持纯函数式风格。方便的 Ramda 包括 useWith 它解决了我原来问题的一个通用版本。它被描述为:

Accepts a function fn and any number of transformer functions and returns a new function. When the new function is invoked, it calls the function fn with parameters consisting of the result of calling each supplied handler on successive arguments to the new function.

换句话说,我原来的 foobar 模式变成了:

//transform the 1st passed argument with R.identity()
//and the 2nd with bar(), pass the results to foo

var foobar = R.useWith(foo, R.identity, bar);

我仍然不知道可以使用下划线或 lodash 开箱即用的方法,这意味着至少现在,Ramda 值得进一步研究。