3

Eloquent Javascript (Chapter 6)の匿名関数コード例を呼び出す sum 関数に問題がありますが、この投稿で明確化された内容は理解していますが、匿名関数がどのように呼び出されるかは本当にわかりません。

私がこのコードを理解していることから:

function forEach(array, action) {
  for (var i = 0; i < array.length; i++)
    action(array[i]);
}

function sum(numbers) {
  var total = 0;
  forEach(numbers, function (number) {
    total += number;
  });
  return total;
}
alert(sum([1, 10, 100, 1000]));

このコードに似ています (他のスレッドの @CKKiller からの支援に感謝します):

numbers = [1, 10, 100, 1000];
for (var i = 0; i < numbers.length; i++) {
  var number = numbers[i];

  function (number) {
    total += number;
  }
}
alert(total);

しかし、2 番目のコード例を実行できません。何が問題なのですか? 私の理解では、構文関数 (数値) {}を呼び出すことはできませんが、最初の例が関数に指示していることではありませんか?

4

3 に答える 3

3

2 番目のコード スニペットでは、匿名関数を宣言しているだけです。それを呼び出すと、正常に動作するはずです。「関数式をすぐに呼び出す」には、次のようにする必要があります。

(function (){
    // Your code
})();

または

(function (){
    // Your code
}());

それらは IIFE と呼ばれます。(上記の引用で)

以下のコメントで user1600680 が指摘したように、コードを編集するにnumberは、パラメーター リストから削除する必要があります。これは次のようになります。

(function () {
  total += number;
})();
于 2012-09-01T13:00:24.707 に答える
2

しかし、2 番目のコード例を実行できません。何が問題なのですか?

名前のない関数宣言があります:

function (number) {
    total += number;
}

関数宣言には、常に関数の名前を含める必要があります。仕様のセクション 13を参照してください。

私の理解では、構文を呼び出すことはできませfunction (number) {}んが、最初の例が関数に指示していることではありませんか?

そうではありません。最初の例では、関数が式のコンテキストで定義されている (他の関数に引数として渡される) ため、関数式があります。関数式に名前は必要ありません。式は関数オブジェクトに評価され、引数として に渡されますforEachfunction (number) {}関数を呼び出すのではなく、関数を定義します。

匿名関数の呼び出し方法がよくわかりません

それについて特別なことは何もありません。重要な側面は、関数が第一級のオブジェクトであることです。つまり、関数は変数に割り当てられ、他の値 (プリミティブ値またはオブジェクト) と同様に他の関数に渡すことができます。 actionは関数を参照するので、その関数を で呼び出すことができますaction()。関数は に直接渡されforEachます:

forEach(numbers, function (number) {
    // ...
});

内部で呼び出されますが、 で定義されているためforEach、 の値を更新できるため、 内部のすべてのローカル変数にアクセスできるクロージャーです。totalsumsum

関数を事前に定義することもできます。

function sum(numbers) {
    var total = 0;
    function add(number) {
       total += number;
    }
    forEach(numbers, add);
    return total;
}

ただし、値を 1 回だけ使用する場合は、最初にそれを変数に代入する (または関数を宣言する) 必要はありません。たとえば、次のように配列を直接渡しましたsum

sum([1, 10, 100, 1000])

最初に変数に代入する代わりに:

var numbers = [1, 10, 100, 1000];
sum(numbers);

同様の動作を示す最初のコードに相当するものは次のとおりです。

var numbers = [1, 10, 100, 1000],
    total = 0,
    action = function(number) { // variable assignment -> expression context
        total += number;
    };

for (var i = 0; i < numbers.length; i++) {
  var number = numbers[i];
  action(number);
}

alert(total);
于 2012-09-01T13:19:57.453 に答える
1

2 番目の例は無名関数を呼び出しませ。関数を宣言するだけです。したがって、 for ループはtotal変数に対して何もしません (以前にどこかで宣言されていると思います)。はalert(total)、total に最後に割り当てられたもののみを出力します (無名関数は呼び出されtotalず、更新されないため)。

于 2012-09-01T13:05:35.563 に答える