2

1 から 9 までの数字に対して JavaScript でいくつかのキー バインディングを設定し、「show1」、「show2」などのラベルが付いたページ上のさまざまなリンクをクリックしようとしています。

問題は、数字のキーバインディングを作成しても問題ありませんが、常に最後のアイテム、つまり「show9」を表示することです。

これは、キーボードで 1 または 2 を押すと、それぞれ 1 と 2 を返すはずの関数が 3 を返す例です。

for i in [1..2]
    key i.toString(), (e) ->
        alert i

http://jsfiddle.net/DARxg/

4

1 に答える 1

3

作成している関数には、関数が作成された時点での変数のコピーではなく、変数への永続的な参照iがあります。そのため、常に最終値 ( 3) が表示されます。

更新:回答の最後にCoffeeScript風の方法がありますが、トレードオフを理解するために全体を読むと便利です。

代わりに、変更されない別の変数を閉じる関数を作成するビルダー関数を使用してください: Updated Fiddle

buildHandler = (value) ->
    (e) ->
        alert value
        return

for i in [1..2]
    key i.toString(), buildHandler i

そこで、ハンドラー関数は渡した引数を閉じているbuildHandlerため、変更されません。

詳細:クロージャーは複雑ではありません(ただし、CoffeeScript ではなく JavaScript に基づいています)


また、即時呼び出し関数式 (IIFE) が本当に好きな人には (IIFE をループで使用することはお勧めしません。理論的には、毎回新しい関数を作成して破棄するだけで、読みにくいです):

for i in [1..2]
    key i.toString(), (
        (value) ->
            (e) ->
                alert value
                return
        )(i)

mu is too shortは、CoffeeScript にはまさにこれを行うためのキーワードがあることをコメントで指摘しています。ドキュメントのこのセクションdoの終わり近くにあります。これを使用すると、次のようになります。

for i in [1..2]
    key i.toString(), do (i) -> (e) ->
        alert i
        return

現在、これは不要な関数を作成して破棄する JavaScript に変換されます (上記の IIFE のように) が、多くのユース ケースでは、おそらく問題にはなりません。おそらく、上記の最初のオプションの明快さを求めるでしょうが、ベルトにたくさんのツールがあるのは良いことです.

于 2013-10-17T06:50:14.457 に答える