Ramda:如何在没有`R.wrap`的情况下修改函数参数?

时间:2016-12-17 23:52:49

标签: javascript ramda.js

如何覆盖方法参数默认值,不包装(因为它即将被删除)。请考虑以下事项。

if($('.show-divs').length == 3) {
    $('#divs-wrapper').removeClass('expand');
}

所以,重新分配foo,默认翻转。每次我调用let foo = (bar, { logToConsole = false }) => { if (logToConsole) console.log(bar); return bar; }; // I want foo to always log, but I want to leave the option open to // override that on a per instance basis (which excludes doing a // `R.partial`). Looking at the methods available, `wrap` seems to // do what I want... foo = R.wrap(foo, (fn, bar, options) => { options = R.merge({ logToConsole: true }, options); return fn(bar, options); } 之后,都会更改默认值。

由于foo已被弃用,我应该使用什么呢?

我跟着this thread,但没有看到如何用那里的例子解决这个模式。

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

我建议采用不同的方法。我假设选项哈希始终是最后一个参数。如果是这种情况,可以写一个装饰器:

function logLastArg(f) {
  return R.curryN(f.length, function() {
    console.log(R.last(arguments));
    return R.apply(f, arguments);
  });
}

function query(queryString, dbOpts) {
  return ['foo', 'bar', 'baz'];
}

var queryWithLogging = logLastArg(query);

query('SELECT username FROM users', {name: 'default'});
// => ['foo', 'bar', 'baz']

queryWithLogging('SELECT username FROM users', {name: 'default'});
// logs "{name: 'default'}"
// => ['foo', 'bar', 'baz']

答案 1 :(得分:1)

这个讨论涉及到大卫表示我可以更加简单地重写我用于包装的每一个用途,特别是ES6方便。

我不确定他是否正确,但距离不远。多年来我一直在使用类似wrap的东西,在JS中做AOP风格的工作,我仍然这样做,只是不在Ramda中使用它。是否所有这些都可以以不同的方式重写,一直写下它们对我来说很有用,但大卫的观点是好的。

我认为,你的案件可以非常直接地重写:

const foo2 = (bar, options) => foo(bar, R.merge({logToConsole: true}, options));

foo2(42);
// logs 42
//=> 42
foo2(99, {logToConsole: false});
// (doesn't log)
//=> 99 

(我假设原件中的command应该是bar。这是正确的吗?)

更新

如果你想重新分配foo,你可以像这样包装那个:

foo = ((orig) => 
  (bar, options) => orig(bar, R.merge({logToConsole: true}, options))
)(foo);

这与上面foo2的行为相同。 (显然,它不适用于const foo的{​​{1}}声明。