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

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

本文关键字:javascript 闭包 参数 函数 转换      更新时间:2023-09-26

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

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:库

Javascript程序员的实用函数库。

我早期的印象似乎是,这是一种对下划线和lodash等库的扩展和改进,同时更严格地坚持纯功能风格。方便的是,Ramda包含了useWith,它解决了我最初问题的通用版本。它被描述为:

接受函数fn和任意数量的transformer函数,并返回一个新函数。当调用新函数时,它会调用函数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值得进一步研究。