0

このコードがそのように機能する理由を誰かが (明確かつ簡潔に) 説明してくれませんか? 私は、クロージャーが存在せず、javascript のように機能しない Java (6 および 7) で強く型付けされたバックグラウンドを持っています。この質問に関連する概念は、クロージャーとスコープチェーンだと思います。

次に例を示します。

var myfuncs = function() {
    var funcs = []
    var i;
    for (i = 0; i < 10; i++) {
       funcs[i] = function() { console.log(i); }
    }
    return funcs;
}

var allfuncs = myfuncs();
allfuncs.forEach(function(fn) { fn(); });

上記の例では 9 回 (10 回) のログが記録されますが、予想と私の直感では 0 ~ 9 回のログが記録されると考えていました。

これが Javascript のように機能するのはなぜですか? クロージャーは非常に強力ですが、その概念を完全に把握しようとしています! 少し変更した例では正しい出力が生成されますが、なぜでしょうか?

var myfuncs = function() {
    var funcs = []
    var i;
    for (i = 0; i < 10; i++) {
       funcs[i] = (function(index) { console.log(index); })(i);
    }
    return funcs;
}

var allfuncs = myfuncs();
allfuncs.forEach(function(fn) { fn(); }); 

クロージャーは Javascript に固有のものではありませんが、ブラウザー/DOM とのインターフェイスとして JavaScript が実際に記述されている場合に、クロージャーが強力である理由を確認したいと思います。

ブラウザー/DOM とのインターフェース時にクロージャー手法を適用する方法の良い実用的な例はありますか?

ありがとう。

4

1 に答える 1

1

あなたが持っている例では、それは非常に簡単です。

最初の例では、変数は 1 つだけでi、すべてがその単一の値を参照します。つまり、数字を910 回出力します。各関数は、その変更の共有値をキャプチャしました。i

2 番目の例では、クロージャを使用しています。各関数には、と呼ばれるプライベート変数があり、値のコピーindexを受け取ります。これが重要な部分です。i

つまり、10 個の関数があり、それぞれにプライベート変数があり、それらの変数のそれぞれがその時点で存在していたスナップショットを取得0するため、うまくいきます。9indexindexi

これは、クロージャーのより長い形式であり、次の場合に役立ちます。

function myFactory(index) {
  return function() {
    console.log(index);
  }
}

var myfuncs = function() {
    var funcs = []
    var i;
    for (i = 0; i < 10; i++) {
       funcs[i] = myFactory(i);
    }
    return funcs;
}

var allfuncs = myfuncs();
allfuncs.forEach(function(fn) { fn(); }); 
于 2014-04-12T04:46:46.297 に答える