JavaScript:连续调用对象上的函数列表

JavaScript: Successively calling a list of functions on an object

本文关键字:函数 列表 对象 连续 调用 JavaScript      更新时间:2023-09-26

假设我有一个函数列表存储在数组中:

var myFunctions = [
    function (i) {return i + 2},
    function (i) {return i * 2},
    function (i) {return i - 3}
]

依次将所有这些函数调用为对象的最佳方法是什么,即获得((n + 2) * 2) - 3作为结果?

欢迎使用外部库(如下划线)回答

数组也是JavaScript对象。在您的示例中,您创建了一个数组和三个属性,即f1, f2f3。相反,您可以简单地执行

var myFunctions = [
    function(i) {
        return i + 2
    },
    function(i) {
        return i * 2
    },
    function(i) {
        return i - 3
    }
];

现在我们有了一个函数数组,我们可以使用Array.prototype.reduce函数来应用这些函数,如下所示

var result = myFunctions.reduce(function(result, currentFunction) {
    return currentFunction(result);
}, n);

n是传递给要应用的函数列表的实际初始值。reduce取初始值和第一个函数,分别作为resultcurrentFunction传递。我们将currentFunction应用于result并返回值。在下一次迭代中,返回值将是result, currentFunction将是第二个函数,以此类推。

如果你不喜欢函数式的方法,你可以简单地使用for循环,像这样

var i = 0, result = 0, n = 10;
for (var i = 0; i < myFunctions.length; i += 1) {
    n = myFunctions[i](n);
}

Using fold (reduce):

var n = 5;
var myFunctions = [
    function (i) {return i + 2},
    function (i) {return i * 2},
    function (i) {return i - 3}
];
n = myFunctions.reduce(function(n, fn) { return fn(n) }, n);
n; // => 11 ((5 + 2) * 2 - 3)

使用函数组合:

var myFunctions = [
    function (i) {return i - 3},
    function (i) {return i * 2},
    function (i) {return i + 2}
];
_.compose.apply(null, myFunctions)(5); // => 11

请注意,在第二个示例中,函数的顺序是相反的,按照惯例,首先应用链中的最后一个函数。

通过一个小的匿名函数提升传递@Sacha的原始需求和@thefourtheye的答案,可以表示为:

const inception = 42; // or anything you prefer really.
const modifiers = [
  i => i - 3,
  i => i * 2,
  i => i + 2
];
// Apply successively each generated function on its predecessor result,
// taking inception as initial origin.
modifiers.reduce((origin, transform) => transform(origin), inception)

还要注意这个代码片段是如何只使用常量的,这更好地反映了源参数从未被改变的事实。