传递给高阶函数的函数中的参数来自何处?

时间:2015-07-27 00:03:29

标签: javascript higher-order-functions

我正在通过Eloquent Javascript工作,我无法理解某些内容。也许我一路上都错过了一些东西。这是第5章(高阶函数),练习1给出的解决方案,它将不同数组中的元素放在一个数组中并将它们全部放在一个数组中:

var arrays = [[1, 2, 3], [4, 5], [6]];
console.log(arrays.reduce(function(flat, current) {
  return flat.concat(current);
}, []));

我的问题是:我完全不知道为什么“平坦”和“当前”的论点在这种情况下起作用。整个章节通过假设读者理解这里发生了什么来阅读,但我完全不知道为什么这样做。似乎没有在任何地方定义“平坦”和“当前”。另一个简短的例子就是作者解释了reduce方法是如何工作的(问题区域以粗体显示):

function reduce(array, combine, start) {
  var current = start;
  for (var i = 0; i < array.length; i++)
    current = combine(current, array[i]);
  return current;
}

**console.log(reduce([1, 2, 3, 4], function(a, b) {
  return a + b;
}, 0));**

世界上“a”和“b”的来源是什么?为什么这段代码有效?非常感谢任何帮助,谢谢。

3 个答案:

答案 0 :(得分:0)

是的,reduce在开始时可能会有点混乱。它是一个带有两个参数的本机函数。一个是回调函数,另一个是任何值。

这个想法是,在回调函数中,您可以一次使用一个数组的值来处理结果。为此,它迭代数组值并将它们传递给您一次定义一个的回调函数,并且对于每个循环,它将获取最后一个循环的值并传递它。

我们假设您想要对数组中的所有数字求和:

//your array
var numbers = [4,7,3];

//your initial value
var initialValue = 0;

//your function
function sum(iteratingValue, arrayValue) {
    return iteratingValue + arrayValue;
}

var result = numbers.reduce(sum, initialValue);

现在,您可以根据需要为回调函数参数命名,abstartfinishfish和{{1} }。这不重要,duck将以相同的顺序传递值。

以下是MDN的定义:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

  

reduce对数组中的每个元素执行一次回调函数,排除数组中的空洞,接收四个参数:初始值(或前一个回调调用的值),当前元素的值,当前索引,以及正在进行迭代的数组。

答案 1 :(得分:0)

flatcurrent不需要在任何地方声明,它们是参数到传递给Array.reduce的匿名函数。

说明这一点的一种方法是修改第二个示例,使用带参数Array.reducea的匿名函数直接使用b。看看这个:

[1, 2, 3, 4].reduce(function(a, b) {
    console.log("a: " + a + " b: " + b);
    return a + b;
});

控制台现在将显示:

a: 1 b: 2
a: 3 b: 3
a: 6 b: 4
10

正在发生的是匿名function(a, b) {...}(1, 2)一起调用,返回3,再次传入(3, 3),返回6,作为第一个参数(6, 4)传入,返回最终答案10

另一个例子是使用第二个参数Array.reduce,比如10,看看发生了什么。 10用作initialValue。所以:

[1, 2, 3, 4].reduce(function(a, b) {
    console.log("a: " + a + " b: " + b);
    return a + b;
}, 10);

跟踪是:

a: 10 b: 1
11 b: 2
13 b: 3
16 b: 4
20

你可以弄清楚发生了什么。

答案 2 :(得分:0)

首先,让我们触及问题的核心。我们假设你有function,就像这样:

function func1(myfunc, arr) {
    //Do something, which will result in having variables called param1 and param2
    myfunc(param1, param2);
}

让我们看看会发生什么。 func1myfuncarr为参数。调用myfunc时将传递func1arr是一个数组。

现在,我们假设您这样称呼它:

func1(function(a, b) {
    //do something with a and b
}, [1, 2, 3, 4]);

您通过传递func1和数组来调用function。数组是显而易见的,所以让我们看看functionfunction需要两个参数,并会对它们执行某些操作。当您致电a时,您无需定义bfunc1,因为创建和初始化它们是func1的内部工作。因此,func1将执行其内部事务并将您的函数作为参数传递。现在,让我们看看你的例子:

var arrays = [[1, 2, 3], [4, 5], [6]];
console.log(arrays.reduce(function(flat, current) {
  return flat.concat(current);
}, []));

在这里,您拨打arrays.reduce(与一般说明中的func1非常相似)。您传递了function和一个数组。同样,数组很明显,但问题是如何定义flatcurrent。答案是创建和初始化它们是arrays.reduce的内部工作。关于reduce原型函数,您可以阅读更多相关信息here