5

私が読んだ記事と同じくらい多くの記事がありますが、まだいくつか質問があります。

私はすでに次のような閉鎖の使用法を知っています(そして理解しています):

  1. 悪名高いループの問題 (番号が保持された、それぞれにアラートがあるリンクのループ)

  2. カウンターの増加(関数を呼び出し続ける->増加した数を警告する)

ここから:

外部関数のローカル変数を参照する内部関数はクロージャを作成します

ここから:

クロージャーは関数のローカル変数であり、関数が戻った後も生き続けます。または、クロージャーは、関数が戻ったときに割り当てが解除されないスタックフレームです。(あたかも「スタック フレーム」がスタック上にあるのではなく、malloc されたかのように!)

3 質問してください:

質問1

JS のすべての関数がクロージャを作成すると言われました。

??? プライベート変数を使用して通常の関数を作成すると、スコープが作成されます。閉鎖ではありません。

閉鎖は次のように機能すると思いました:(ここから)

  1. 外側の「関数メーカー」関数を作成します。
  2. その中でローカル変数を宣言します。
  3. 外側の関数内で内側の関数を宣言します。
  4. 内側の関数内で外側の関数の変数を使用します。
  5. 外側の関数が内側の関数を返すようにする
  6. 関数を実行し、その戻り値を変数に割り当てます

例:

function functionMaker(){
   var x = 1;
   function innerFunction(){
     alert(x);
     x++;
   }
   return innerFunction;
}

では、なぜすべての js 関数がクロージャを作成すると彼らは言うのでしょうか?

質問2

Self-Invoking Functions別名 IEFA -閉鎖Immediately Invoked Function Expressionを作成しますか?

見つめている

(function (a) {
    alert(a);
})(4);

上記の6 つのルールのようなパターンが見当たりません: ここは正確にHave the outer function return the inner functionはどこですか? 単語が表示されませんreturn

質問#3

function myFunction() {
  var myVar = 1;
  var alertMyVar = function () {
    alert('My variable has the value ' + myVar);
  };
  setTimeout(alertMyVar, 1000 * 3600 * 24);
}
myFunction();

myFunctionここで一日中生きていたのですか?またはそれは直後に終了しましたsetTimeoutか?もしそうなら、どうやってその値をSetTimeOut 覚えましたか?

それを正しくするのを手伝ってください。

4

1 に答える 1

8

すべての関数呼び出しでクロージャが作成されます。注意すべき重要なことは、クロージャーが関数呼び出しの存続期間を超えて持続するかどうかです。

すぐに実行される関数を実行する場合:

var value = (function() {
  return 4;
})();

その後、クロージャーが作成されますが、関数が戻ると破棄されます。なんで?クロージャーで定義されたシンボルへの生き残った参照がないためです。しかし、ここで:

var value = function() {
  var counter = 0;
  return function() {
    return counter++;
  };
}();

クロージャーは、元の関数で定義された「カウンター」シンボルへの参照を含む別の関数を返すため、すぐに実行された関数の後も存続します。返された関数はまだ「生きている」ため、ランタイム システムはクロージャを保持する必要があります。

ここで注意してください:

var value = function() {
  return function(a) {
    return "hello " + a;
  };
}();

外側のすぐに実行される関数が関数を返しますが、その関数は外側の関数からのシンボルを参照しないため、クロージャを保持する必要はありません。

私が言おうとしているのは、クロージャーを厳密に静的で構造的なものとしてではなく、関数の実行の効果の一部として考えることが役立つということです。永続的なクロージャを時々作成する関数を持つことは可能ですが、常にではありません。

于 2012-11-21T15:05:01.940 に答える