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

时间:2015-02-05 16:17:08

标签: javascript node.js underscore.js

我不时发现自己在节点中使用以下模式。

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

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

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

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


尝试解决方案

foobar的组合很接近(这使我考虑下划线_.compose的变体),但转换后的值只是传递给{{foo的参数之一1}}。

我需要新的实用程序功能(并且可能不适用于非原始参数)的不优雅解决方案是:

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)

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

1 个答案:

答案 0 :(得分:0)

我最近找到了图书馆Ramda

  

Javascript程序员的实用函数库。

我早期的印象似乎是尝试扩展和改进图书馆,如下划线和lodash,同时更严格地坚持纯粹的功能风格。方便地,Ramda包括useWith,它解决了我原始问题的通用版本。它被描述为:

  

接受函数fn和任意数量的变换器函数并返回一个新函数。当调用新函数时,它调用函数fn,其参数包括在新函数的连续参数上调用每个提供的处理程序的结果。

换句话说,我的原始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值得进一步调查。