使用多个参数编写javascript函数

时间:2017-06-19 08:15:47

标签: javascript functional-programming ecmascript-6

如何将此功能组合转换为更易读的格式?

funcA(argumentA, funcB(argumentA, funcC(argumentA, argumentB)))

我想要达到的目标更像是:

compose(funcC, funcB, funcA)(argumentA, argumentB)

我正在使用这个撰写函数实现:

const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args)))

问题是我需要在所有函数调用中将argumentA作为第一个参数,并且每个函数都返回一个值作为第二个参数传递给下一个函数。我知道我可以创建单独的函数返回函数并像这样使用它们:

compose(funcCWithArg(argumentA), funcBWithArg(argumentA), funcAWithArg(argumentA))(argumentB)

但在我的实际情况中,它们中只有三个,但更多,这需要一些大量的代码才能写下来。有更简单的方法吗?

编辑:我无法使用任何外部库。只有香草js。

3 个答案:

答案 0 :(得分:1)

编写这样的函数并不难:

const link = (...fns) => (a, ...args) =>
    fns.slice(1).reduce((val, fn) => fn(a, val), fns[0](a, ...args));

如果您希望它足够强大以便优雅地处理错误,那么需要更多。但这应该是一个开始。

您可以这样使用它:

const funcA = (x, y) => `funcA(${x}, ${y})`;
const funcB = (x, y) => `funcB(${x}, ${y})`;
const funcC = (x, y) => `funcC(${x}, ${y})`;

link(funcA, funcB, funcC)('argumentA', 'argumentB');
//=> "funcC(argumentA, funcB(argumentA, funcA(argumentA, argumentB)))"

您可以在 on Runkit 中看到这一点。

(显然,如果你想要相反的参数顺序,你可以做reverse。)

答案 1 :(得分:0)

首先使用bind创建属于部分应用程序的新函数。然后使用您已有的compose函数:

const funcA = (x, y) => `A(${x}, ${y})`;
const funcB = (x, y) => `B(${x}, ${y})`;
const funcC = (x, y) => `C(${x}, ${y})`;

const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args)));
const partials = (...fns) => (...args) => fns.map((f) => f.bind(this, ...args));

console.log(compose(...partials(funcA, funcB, funcC)("a"))("b"));

// Output:
// A(a, B(a, C(a, b)))

<强>更新

您还可以构建一个函数,该函数使用传递的第一个参数组成partial,然后使用其他参数调用它们。 (我认为这就是你想要的?我不能100%确定如何处理两个以上的论点。)

const partialCompose = (...fns) => (...args) => compose(...partials(...fns)(args[0]))(...args.slice(1));

console.log(partialCompose(funcA, funcB, funcC)("a", "b")); // same output as above

答案 2 :(得分:0)

使用vanilla JS,

const compose = (...fns) => (arg1, arg2) => fns.reduce((arg, f) => f(arg1, arg), arg2);

<强>解释

compose成为一个返回函数的函数,它循环传递给它的函数列表,将第一个参数传递给每个函数调用。

<强>测试

const sum = (a, b) => (a + b);
const mult = (a, b) => (a * b);
compose(sum, mult)(2, 3) === mult(2, sum(2, 3));  // true