1

これらの機能の違いは何ですか? 最初のものは機能し、2 つ目は期待どおりに機能しないのはなぜですか?

http://jsfiddle.net/GKDev/x6pyg/ (これは動作します)

http://jsfiddle.net/GKDev/bv4em/ (これは違います)

入力要素をループして、それらに onfocus イベントを追加しようとしています:

for (var i = 0; i < helpText.length; i++) {
    var item = helpText[i];

    document.getElementById(item.id).onfocus = function() {
        showHelp(item.help);
    };
}
4

3 に答える 3

2

動作しない例では、匿名関数が呼び出されると、ループの実行が終了itemしたときに保持されていた最後の値があります。forこれは、この変数がforループを含む親関数に属しているためです。

実際の例では、新しい関数を作成し、現在の値を次のitemように渡します。

function (help) {
            return function () {
                showHelp(help); // <-- This will be the value enclosed in this anonymous function
            };
        }(item.help); // <-- Calls an anonymous function passing in the current value

これにより、その反復中に存在していた値の周りに新しいクロージャが作成されます。無名関数が呼び出されると、そのローカル値が使用されます。

于 2013-03-28T22:33:41.990 に答える
2

次のように扱われます。

var item;

for (var i = 0; i < helpText.length; i++) {
    item = helpText[i];

    document.getElementById(item.id).onfocus = function() {
        showHelp(item.help);
    };
}

フォーカス コールバックが発生する前にループが終了し、その時点itemで最後のアイテムが割り当てられます。

于 2013-03-28T22:33:56.917 に答える
1

実際、それはかなり簡単です。

最初のケースでは、ローカル コピーとして機能するクロージャ内で item.help を渡しています。それはその範囲の囚人のようなものです。外で何が起こっても、誰も気にしません。

for (var i = 0; i < helpText.length; i++) {
        var item = helpText[i];
        document.getElementById(item.id).onfocus = function (help) {
            return function () {
                showHelp(help);
            };
        }(item.help);
    }

2 番目の例では、item の値を保持するクロージャはありません。つまり、item が評価されると、実際の値、つまり配列の最後の要素に評価されます。これは、 for の最後のループがその値を に設定するためです。配列の最後の値。

for (var i = 0; i < helpText.length; i++) {
    var item = helpText[i];
    document.getElementById(item.id).onfocus = function() {
      showHelp(item.help);
    }
  }
于 2013-03-28T22:36:46.287 に答える