传递给高阶函数的函数中的参数来自哪里?
Where do the arguments in functions passed to higher-order functions come from?
我正在研究 Eloquent Javascript,但我无法理解某些内容。也许我一路上错过了什么。这是第 5 章(高阶函数)练习 1 给出的解决方案,它将不同数组中的元素放入一个数组中:
var arrays = [[1, 2, 3], [4, 5], [6]];
console.log(arrays.reduce(function(flat, current) {
return flat.concat(current);
}, []));
我的问题是:我完全不知道为什么参数 "flat" 和 "current" 在这种情况下有效。假设 reader 理解这里发生的事情,通读整章,但我完全不知道为什么会这样。 "flat" 和 "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" 到底从哪里来的?为什么这段代码有效?任何帮助将不胜感激,谢谢。
是的,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);
现在,您可以随意命名回调函数参数,a
和 b
、start
和 finish
、fish
和 duck
。没关系,reduce
将以相同的顺序传递值。
这里是 MDN 的定义:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
reduce executes the callback function once for each element present in the array, excluding holes in the array, receiving four arguments: the initial value (or value from the previous callback call), the value of the current element, the current index, and the array over which iteration is occurring.
flat
和current
不需要在任何地方声明,它们是传递给[=16=的匿名函数的参数 ].
说明这一点的一种方法是修改您的第二个示例以使用带有参数 a
和 b
的匿名函数直接使用 Array.reduce
。看看这个:
[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
发生的事情是用 (1, 2)
调用匿名 function(a, b) {...}
,其中 returns 3
再次传入 (3, 3)
,其中 returns 6
作为第一个参数传入 (6, 4)
,returns 最终答案 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
你可以弄清楚这是怎么发生的。
首先,让我们触及问题的核心。假设你有一个 function
,像这样:
function func1(myfunc, arr) {
//Do something, which will result in having variables called param1 and param2
myfunc(param1, param2);
}
让我们看看会发生什么。 func1
以 myfunc
和 arr
作为参数。 myfunc
会在调用 func1
时传递。 arr
是一个数组。
现在,假设您这样称呼它:
func1(function(a, b) {
//do something with a and b
}, [1, 2, 3, 4]);
您正在通过传递一个 function
和一个数组来调用 func1
。数组很明显,让我们看看function
。 function
需要两个参数并将对它们进行处理。您不必在调用 func1
时定义 a
或 b
,因为创建和初始化它们是 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
和一个数组。同样,数组很明显,但问题是,flat
和 current
是如何定义的。答案是创建和初始化它们是 arrays.reduce
的内部工作。关于 reduce
原型函数,你可以阅读更多关于它的内容 here.
我正在研究 Eloquent Javascript,但我无法理解某些内容。也许我一路上错过了什么。这是第 5 章(高阶函数)练习 1 给出的解决方案,它将不同数组中的元素放入一个数组中:
var arrays = [[1, 2, 3], [4, 5], [6]];
console.log(arrays.reduce(function(flat, current) {
return flat.concat(current);
}, []));
我的问题是:我完全不知道为什么参数 "flat" 和 "current" 在这种情况下有效。假设 reader 理解这里发生的事情,通读整章,但我完全不知道为什么会这样。 "flat" 和 "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" 到底从哪里来的?为什么这段代码有效?任何帮助将不胜感激,谢谢。
是的,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);
现在,您可以随意命名回调函数参数,a
和 b
、start
和 finish
、fish
和 duck
。没关系,reduce
将以相同的顺序传递值。
这里是 MDN 的定义:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
reduce executes the callback function once for each element present in the array, excluding holes in the array, receiving four arguments: the initial value (or value from the previous callback call), the value of the current element, the current index, and the array over which iteration is occurring.
flat
和current
不需要在任何地方声明,它们是传递给[=16=的匿名函数的参数 ].
说明这一点的一种方法是修改您的第二个示例以使用带有参数 a
和 b
的匿名函数直接使用 Array.reduce
。看看这个:
[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
发生的事情是用 (1, 2)
调用匿名 function(a, b) {...}
,其中 returns 3
再次传入 (3, 3)
,其中 returns 6
作为第一个参数传入 (6, 4)
,returns 最终答案 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
你可以弄清楚这是怎么发生的。
首先,让我们触及问题的核心。假设你有一个 function
,像这样:
function func1(myfunc, arr) {
//Do something, which will result in having variables called param1 and param2
myfunc(param1, param2);
}
让我们看看会发生什么。 func1
以 myfunc
和 arr
作为参数。 myfunc
会在调用 func1
时传递。 arr
是一个数组。
现在,假设您这样称呼它:
func1(function(a, b) {
//do something with a and b
}, [1, 2, 3, 4]);
您正在通过传递一个 function
和一个数组来调用 func1
。数组很明显,让我们看看function
。 function
需要两个参数并将对它们进行处理。您不必在调用 func1
时定义 a
或 b
,因为创建和初始化它们是 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
和一个数组。同样,数组很明显,但问题是,flat
和 current
是如何定义的。答案是创建和初始化它们是 arrays.reduce
的内部工作。关于 reduce
原型函数,你可以阅读更多关于它的内容 here.