2

私はshortcut.jsを使用してキーボード入力を処理していますが、目標を達成するためのより効率的な方法があるかどうか疑問に思っています(現在、同じコードのほとんどがコピーされて貼り付けられています)。

たとえば、私は持っています:

  shortcut.add("0",function() {
    points = -1;
    sec = 0;
  }); 

  shortcut.add("1",function() {
    points = 1;
    sec = 0;
  }); 

  shortcut.add("2",function() {
    points = 2;
    sec = 0;
  }); 

  shortcut.add("3",function() {
    points = 3;
    sec = 0;
  }); 

理想的には、ユーザーが0を入力した場合を除いて、入力されたキーが実際にポイント変数に割り当てられるように関数を一般化できます。その場合、ポイント変数は-1に設定されます。

これを実現する方法について何かアイデアはありますか?ありがとうございました!

4

1 に答える 1

3

クロージャーを含むループは、トリックを行う必要があります。

for (var i = 0; i <= 9; ++i) {
    (function(i) {  // Capture current value of 'i' in this scope.
        shortcut.add(i.toString(), function() {
            points = i || -1;  // 'i' if 'i' is not 0, else -1.
            sec = 0;
        });
    })(i);
}

次のコメントを更新します。では、なぜここで閉鎖が必要なのですか? で、最後(i);はどういう意味ですか?

基本的に、渡された無名関数はshortcut.add()すぐには呼び出されず、ループが終了した後で呼び出されるため、クロージャーが必要です。i関数は、値ではなく参照によってキャプチャします。つまり、定義された時点ではなく、実行時にi現在の値が表示されます。

したがって、shortcut.add()ループ本体から直接呼び出すと、渡すすべての無名関数はi、ループが終了した後にその値が current であることを確認することになり、常に同じになります ( 10)。

各反復で新しい変数を作成すると、機能するように見えますが、機能しません。

for (var i = 0; i <= 9; ++i) {
    var _i = i;  // Create new variable containing current value of 'i'.
    shortcut.add(i.toString(), function() {
        points = _i || -1;  // Won't work, '_i' is always 9.
        sec = 0;
    });
}

forループ本体は Javascript で独自のスコープを持たないため、_iと同じように関数スコープで終了しi、同じ方法でキャプチャされます (その最終値は、適用されないため、9代わりに になります)。10++i

したがって、ここで本当に必要なのは、反復ごとに新しいスコープです。これを実現するには、ループ内で関数を定義し、すぐに呼び出して、現在の値を渡しますi

var newScope = function(i) {
    // Here, the value of 'i' will be the one current when 'newScope' is called
    // and will not change, even if 'i' is captured by other functions.
};
newScope(i);  // Call function with current value of 'i'.

最後に、呼び出し演算子を関数定義にnewScope直接適用することで、名前を導入せずにそれを行うことができます。()

(function(i) {
    // Here, the value of 'i' will be the one current when this function is
    // called and will not change, even if 'i' is captured by other functions.
})(i);  // Call function with current value of 'i'.

これがあなたの質問に適切に答えてくれることを願っています。そうでない場合は、お気軽にコメントを残してください。クロージャーの詳細については、 MDN の Closures を参照してください。

于 2012-06-26T13:03:19.073 に答える