2

匿名関数に関する質問をまた出してしまい、大変申し訳ありませんが、それらを理解するたびに、javascript が別のカーブ ボールを投げてくれるようです。

私はKineticJSを使用していくつかの円を作成し、そのようにアニメーション化しています(これらのチュートリアルに従ってください)

for ( i = 0; i < rows; i++ )
{
   for ( j = 0; j < cols; j++ )
   {
      index = i * cols + j;
      circles [ index ] = new Kinetic.Circle({...});
      ...
   }
}
...
for ( i = 0; i < rows; i++ )
{
   for ( j = 0; j < cols; j++ )
   {
      index = i * cols + j;
      anims [ index ] = new Kinetic.Animation({func: function ( frame )
            {
               ( function ( innerCircle )
               {
                  ...
               } ( circles [ index ] ) );
            },
            node: layer
         }
      );
   }
}

index私の意図は、無名関数を作成するときに現在の値を渡すことです。問題は、最後の画像だけがアニメーション化されており、その理由がわかりません。ここに完全なjsfiddleがあります

4

1 に答える 1

3

新しい変数スコープを作成するはずの関数が間違った場所にあります。渡される関数の外にある必要があり、新しい関数を返す必要があります。

返された関数は、目的の値にアクセスできます。

for ( i = 0; i < rows; i++ )
{
   for ( j = 0; j < cols; j++ )
   {
      index = i * cols + j;
      anims [ index ] = new Kinetic.Animation({func: function(innerCircle) {
                                                        return function ( frame ) {

                                                        };
                                                      })(circles[index]),
            node: layer
         }
      );
   }
}

しかし、正直なところ、このような関数をインライン化しないでください。関数を返す名前付き関数を作成すると、非常に明確になります。

function makeFunc(innerCircle) {
    return function (frame) {
           // you can use innerCircle in here
    };
}

for ( i = 0; i < rows; i++ ) {
   for ( j = 0; j < cols; j++ ) {
      index = i * cols + j;
      anims [ index ] = new Kinetic.Animation({
         func: makeFunc(circles[index]),
         node: layer
      });
   }
}

何らかの理由でこれらのインライン関数が好きな人もいますが、混乱を招くだけだと思います。名前付き関数はコードを少し分割し、コードに小さなドキュメントを追加します。

また、ループの反復ごとに新しいインライン関数を作成しないため、わずかに効率的です。代わりに、同じものを再利用してハンドラーを構築しています。

于 2012-10-10T21:25:45.857 に答える