2

私は昨夜から午前中にかけて第 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.` //

私はしばらくの間、この例に頭を悩ませようとしてきました。誰かが良い説明や他のドキュメントを読んで知っているなら、私はそれを大いに感謝します、ありがとう!

4

3 に答える 3

2

これを簡単に説明できるかどうか見てみましょう。

このforEach()関数は 2 つのパラメーターを受け入れます。最初に呼び出されるパラメーターarrayは明らかに配列または配列のようなオブジェクトであり、2 番目に呼び出されるパラメーターactionは実際には関数です。

forEach()渡された配列の各要素にアクセスし、2 番目のパラメーターとして渡された関数を配列の各要素に適用します。

そのため、配列内の各要素にforEach()渡された関数を呼び出し、action配列要素をパラメーターとして関数に渡します。

この関数sum(numbers)は、あなたが持っているように配列を受け入れ、forEach()無名関数を使用してその配列内の数値の合計を計算するために内部で使用します。

無名関数は、渡された配列内の各要素に対して 1 回呼び出されるため、配列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 関数は無名関数と同じことを行います。累積関数が合計関数のスコープ内で宣言されている場合、合計変数は累積関数に対してグローバル (既知) のようになり、最初のパラメーターは必要ないため、関数は既に作成した関数のようになります。知る:

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

残っているのは反復を抽出することであり、コードはこの本のようになります。

于 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;
   }
 }

最小要素についても同様:

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 に答える