0

次のトピックを読んでいましたJavaScriptクロージャーはどのように機能しますか? そして、このコードを見つけました:

function foo(x) {
  var tmp = 3;
  return function (y) {
    alert(x + y + tmp);
    x.memb = x.memb ? x.memb + 1 : 1;
    alert(x.memb);
  }
}
var age = new Number(2);
var bar = foo(age); // bar is now a closure referencing age.
bar(10);

著者は次のようにコメントしています。

予想どおり、 を呼び出すたびにbar(10)がインクリメントされますx.memb。予想外かもしれませんが、それxは age 変数と同じオブジェクトを参照しているだけです! バーに数回電話した後、にage.membなります2

なぜ常に2を返すのか混乱しています。どのようにして常に 2 になるのか説明してもらえますか?

4

4 に答える 4

2

ここで起こっていることは次のとおりです。foo は、呼び出されると、最初に foo に渡されたオブジェクトの memb プロパティをインクリメントする関数を返します。

そのパラメーター オブジェクトである age は、単純なオブジェクトであることがより明確になります。しかし、元の作成者はおそらくここで楽しんでいるので、新しい Number を渡します。Javascript に関する限り、これはどのオブジェクトよりも有効です。

したがって、bar が呼び出されると、その Number オブジェクトの memb プロパティが作成/インクリメントされます。

その数値の「内部値」は変更されません。常に 2 ですが、age.memb は毎回 1 ずつ増加します。それが著者の意味するところです:

bar を数回呼び出した後、age.memb は 2 になります。

ここでの 2 は、数回 (つまり 2 回) インクリメントされた後の memb の値を指します。これは、age がたまたま最初にあった Number の値とは関係ありません。bar を再度呼び出すと、age.memb は 3 になります。

于 2012-08-21T09:49:35.750 に答える
0

私が正しく理解していれば、バーの関数ポインタのようなものを取得できます。これは、名前のない関数を指します。この名前のない関数は、常に同じ入力を受け取ります。これは、foo が 1 回だけ呼び出されるためです。つまり、x は変更されません。その結果、名前のない関数にはメモリがなく、常に結果として x の入力値が得られます。

于 2012-08-21T09:49:15.903 に答える
0

「常に」2になるわけではありません。

著者は次のように述べています。

4 回呼び出した後は 4 になります。

これをfirebugコンソールに貼り付けるだけです:

function foo(x) {
  var tmp = 3;
  return function (y) {
    //console.log(x + y + tmp);
    x.memb = x.memb ? x.memb + 1 : 1;
    console.log(x.memb);
  }
}
var age = new Number(2);
var bar = foo(age); // bar is now a closure referencing age.
bar(10);
bar(10);
bar(10);
bar(10);

console.log('result: ', age.memb)    // result: 4
于 2012-08-21T09:49:39.103 に答える
0

bar(10) には foo(2) への参照があります

したがって、bar(10) を呼び出すたびに。パラメータyが10で、バーの年齢参照が2であるため、fooの内部関数(クロージャ)を実行します。したがって、バー(10)を呼び出すと年齢は常に2になり、値に応じてyは10程度になります提供。Closure は基本的に、外部関数が存在しない場合でも内部関数への参照を保存します。

于 2012-08-21T09:43:24.373 に答える