我昨晚和整个上午一直在阅读第5章,似乎无法获得更高阶的功能概念。以下是示例: //我理解第一个函数,我将它包含在内,因为它用于下一个函数。
function forEach(array, action) {
for (vari = 0; i < array.length; i++)
action(array[i]);
}
forEach(["Wampeter", "Foma", "Granfalloon"], print);
function sum(numbers) {
var total = 0;
forEach(numbers, function(number) {
total += number;
});
return total;
}
根据我的理解,函数sum是取参数数字,我认为它是一个数组?现在,当调用forEach函数(在sum中)时,它将传递给sum的数组编号,然后它也需要一个匿名函数?
我真的很困惑这个匿名函数实际上在做什么。它取参数是什么,但它还做了什么?这个匿名函数是否意味着在该参数中,如print或show这样的函数会传递参数号吗?换句话说,它看起来像这样
function([10,12,11]) {
var total = 0
forEach([10,12,11]), show(???)
//at this point it would iterate over the array, and use the action passed to display `//the pointer in the array. What I think is happening is that it is taking this pointer value and adding it to the total.` //
我一直试图绕过这个例子一段时间,如果有人知道一个好的解释或任何其他文件来阅读我会非常感谢,谢谢!
答案 0 :(得分:2)
让我看看我是否可以轻松地为您解释:
forEach()
函数接受两个参数,第一个名为array
,显然是一个数组或类似数组的对象,第二个名为action
的参数实际上是一个函数。
forEach()
访问传递给它的数组中的每个元素,并将作为第二个参数传递给它的函数应用于数组中的每个元素。
因此,forEach()
为数组中的每个元素调用传递给它的函数action
,并为函数提供数组元素作为参数。
函数sum(numbers)
接受一个数组,但它本身使用forEach()
来计算使用匿名函数的数组之和。
请记住,对于传递给sum()
的数组中的每个元素,都会调用一次匿名函数,因此它实际上对数组中的元素求和。
答案 1 :(得分:2)
匿名函数适用于每个当前选定的元素。如果展开(逐步执行)循环(伪代码,*表示当前元素),您可以更好地了解的工作方式:
var total = 0;
forEach([*1, 2, 3]), fun(1)) => total = 0 + 1 = 1
forEach([1, *2, 3]), fun(2)) => total = 1 + 2 = 3
forEach([1, 2, *3]), fun(3)) => total = 3 + 3 = 6
您可以像这样重写 sum 函数:
// because there is no "pass by reference" in JavaScript for
// "simple" types, total must be wrapped in an object
// in order to return the sum through the parameter for the showcase
var result = { total: 0 }
function sum(numbers_array) {
for (var i = 0; i < numbers_array.length; i++) {
accumulate(result, numbers_array[i]);
}
}
function accumulate(acc, number) {
acc.total += number;
}
在这种情况下,accumulate函数与匿名函数的作用相同。当累积函数在 sum 函数的范围内声明时, total 变量就像累积的全局(已知)函数,然后不需要第一个参数,所以函数就像你已经知道的那样:
var total = 0;
function sum(numbers_array) {
function accumulate(number) {
total += number;
}
for (var i = 0; i < numbers_array.length; i++) {
accumulate(numbers_array[i]);
}
}
下一步是提取并传递accumulate函数作为参数:
var total = 0;
function accumulate(number) {
total += number;
}
// notice, that JavaScript knows how many parameters your function expects
function sum(numbers_array, action) {
for (var i = 0; i < numbers_array.length; i++) {
action(numbers_array[i]);
}
}
剩下的就是提取迭代,代码在本书中看起来就像这样。
答案 2 :(得分:0)
简单来说:使代码更通用,更简洁。
例: 让我们说我们想要在数组中找到最大元素: 这很简单,很酷: 在java脚本中,我们将写:
var array = [10,20,30,40,50,60]
function maxEle(array){
var max = array[0];
for(var i=0;i< array.length;i++){
if(max < array[i]){
max = array[i];
}
}
console.log(max);
}
所以这会给我一个数组中的最大元素。
现在几天之后,有人问我你的最大功能非常酷,我想要一个能在阵列中打印最小值的功能。 我将再次重做同样的事情,我正在寻找Max。
function minEle(array){
var min = array[0];
for(var i=0;i< array.length;i++){
if(min > array[i]){
min = array[i];
}
}
console.log(min);
}
现在这也很酷。 一段时间后,出现了另一个要求:我想要一个能打印数组所有元素之和的函数。
此外,代码将类似于我们迄今为止所写的内容,除非它现在将执行求和。
function sumArr(array){
var sum = 0;
for(var i=0;i< array.length;i++){
sum = sum + array[i];
}
}
console.log(sum);
}
观察: 在编写了这些代码之后,我在每个函数中重写几乎相同的东西,遍历数组然后执行一些操作。 现在编写重复代码并不是一件很酷的事情。 因此,我们将尝试封装变化的部分,即动作即最小值,最大值,总和。 因为它可以将函数作为参数传递给FPL中的函数。 因此,我们将重新考虑我们之前编写的代码,现在编写一个更通用的函数。
var taskOnArr = function(array, task){
for(var i=0;i<array.length;i++){
task(array[i]);
}
}
现在这将是我们的通用函数,它可以对Array的每个元素执行任务。
现在我们的任务将是:
var maxEle = array[0];
var taskMaxEle = function(ele){
if(maxEle < ele){
maxEle = ele;
}
}
同样适用于min元素:
var minEle = array[0];
var taskMinEle = function(ele){
if(minEle > ele){
minEle = ele;
}
}
也用于数组的总和:
var sum = 0;
var taskSumArr = function(ele){
sum = sum + ele;
}
现在我们需要将函数传递给taskOnArr函数:
taskOnArr(array,taskSumArr);
console.log(sum);
taskOnArr(array,taskMinEle);
console.log(minEle);
taskOnArr(array,taskMaxEle);
console.log(maxEle);