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

Javascript Ramda:如何在没有R.wrap的情况下修改函数参数?,javascript,ramda.js,Javascript,Ramda.js,如何在不换行的情况下覆盖methods参数默认值(因为它即将被删除)。请考虑以下内容: 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 ins

如何在不换行的情况下覆盖methods参数默认值(因为它即将被删除)。请考虑以下内容:

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,默认值翻转。每次我在之后调用
foo
,它都会更改默认值

既然
wrap
已被弃用,我应该使用什么替代

我继续,但并没有看到如何用这里的例子来解决这个模式


谢谢你的帮助

我建议另一种方法。我假设选项哈希始终是最后一个参数。如果是这种情况,可以编写装饰程序:

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']

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

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']

讨论涉及到David,他展示了我为wrap提出的每一个用法都可以更简单地重写,特别是使用ES6 handy

我不确定他是否是对的,但这并不遥远。多年来,我一直在使用类似于
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 
(我假设原始版本中的
命令
应该是
。正确吗?)

更新 如果您希望重新分配
foo
,您可以将其包装如下:

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

这将具有与上面的
foo2
相同的行为。(显然,它不适用于您的
const
声明
foo

讨论涉及到David,它表明我为wrap想到的每个用法都可以更简单地重写,尤其是使用ES6 handy

我不确定他是否是对的,但这并不遥远。多年来,我一直在使用类似于
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 
(我假设原始版本中的
命令
应该是
。正确吗?)

更新 如果您希望重新分配
foo
,您可以将其包装如下:

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

这将具有与上面的
foo2
相同的行为。(显然,它不适用于
foo
const
声明)

请注意,原始文件使用了options对象来确定是否要登录。在本例中,它实际记录的是第一个参数。我认为理想情况下,这应该在不重写原始函数的情况下完成,因为这可能是外部API的一部分。@davidchambers。我不确定我是如何看到这个解决方案与我用上面的wrap实现的一样。除非您只是展示了您可以记录任何部分(就像我可以在调用原始方法之前控制台记录
R.last(arguments)
之外的内容一样)。另请参见@ScottSauyet回答中的我的担忧。请注意,原始版本使用options对象来确定是否要登录。在本例中,它实际记录的是第一个参数。我认为理想情况下,这应该在不重写原始函数的情况下完成,因为这可能是外部API的一部分。@davidchambers。我不确定我是如何看到这个解决方案与我用上面的wrap实现的一样。除非您只是展示了您可以记录任何部分(就像我可以在调用原始方法之前控制台记录
R.last(arguments)
之外的内容一样)。另请参见@ScottSauyet回答中的我的担忧。感谢您的回复!关于
命令
,您的回答是正确的-我更新了这个问题。在这个问题和其他@davidchambers的回答中,“wrapping”方法的返回利用了调用原始方法的优势。这使得无法重新分配原始方法。您表示重新分配原始方法不太理想,但在我的情况下,我想这样做。用例是我只想在一个地方关心日志逻辑和可能的覆盖。我在文件的其余部分调用原始方法,不管那里发生了什么。我想您会建议我总是将它分配给一个新变量,而不管修改如何。@Rhilgefort:已更新以允许重新分配。。。这并不是我推荐的技术。感谢您的更新(我更新了问题,使其不使用
const
)。我理解不要覆盖的警告。这是好的和干净的,再次感谢您花时间回复。总的来说,我非常喜欢向拉姆达和FP的转变。感谢您的回复!关于
命令
,您的回答是正确的-我更新了这个问题。在这个问题和其他@davidchambers的回答中,“wrapping”方法的返回利用了调用原始方法的优势。这使得无法重新分配原始方法。您表示重新分配原始方法不太理想,但在我的情况下,我想这样做。用例是我只想在一个地方关心日志逻辑和可能的覆盖。我在文件的其余部分调用原始方法,不管那里发生了什么。我想您会建议我总是将它分配给一个新变量,而不管修改如何。@Rhilgefort:已更新以允许重新分配。。。这并不是我推荐的技术。感谢您的更新(我更新了问题,使其不使用
const
)。我理解不要覆盖的警告。这是好的和干净的,再次感谢您花时间回复。总的来说,我非常喜欢向拉姆达和FP的转变。