2

I have been reading through Chapter 5 last night and throughout the morning and can't seem to get the higher order functions concepts to stick. Here are the examples: //I understand this first function, I am including it because it is used in the next function.

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;

}

To my understanding the function sum is taking the argument numbers, which I believe comes in as an array? Now, when the forEach function is called (within sum), it takes the array numbers passed to sum and then it also takes an anonymous function?

I am really confused on what this anonymous function is actually doing. It is taking the parameter number but what else is it doing? Does this anonymous function imply that in that parameter, a function like print or show will be passed the parameter number? In other words it would look something like this

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.` //

I have been trying to wrap my head around this example for a while, if anyone knows of a good explanation or any other documentation to read over I would greatly appreciate it, thanks!

4

3 回答 3

2

让我看看我是否可以轻松地为您解释这一点:

forEach()函数接受两个参数,第一个调用array的显然是一个数组或类似数组的对象,第二个调用的参数action实际上是一个函数。

forEach()访问传递给它的数组中的每个元素,并将作为第二个参数传递给它的函数应用于数组中的每个元素。

所以forEach()调用传递给它的函数,为action数组中的每个元素命名,并将数组元素作为参数提供给函数。

该函数sum(numbers)像您一样接受一个数组,并在其forEach()内部使用匿名函数计算该数组中数字的总和。

请记住,对于传递给的数组中的每个元素都会调用一次匿名函数,sum()因此它实际上是对数组中的元素求和。

于 2013-10-27T15:51:28.127 回答
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函数的范围内声明了accum函数时, total变量对于 accum 函数就像是全局的(已知的),那么就不需要第一个参数了,所以函数就变成了你已经知道的那个知道:

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]); 
    }
}

下一步是提取并传递累积函数作为参数:

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]); 
    }
}

剩下的就是提取迭代,代码看起来就像书中的这个。

于 2013-10-27T15:55:46.927 回答
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;
   }
}

也用于 Array 的求和:

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);
于 2015-03-21T18:38:03.970 回答